summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--absl/BUILD.bazel15
-rw-r--r--absl/algorithm/CMakeLists.txt4
-rw-r--r--absl/base/CMakeLists.txt34
-rw-r--r--absl/base/internal/raw_logging.cc3
-rw-r--r--absl/base/internal/sysinfo_test.cc6
-rw-r--r--absl/base/internal/unscaledcycleclock.h3
-rw-r--r--absl/container/CMakeLists.txt43
-rw-r--r--absl/container/inlined_vector.h6
-rw-r--r--absl/container/internal/raw_hash_set.h8
-rw-r--r--absl/container/internal/raw_hash_set_test.cc11
-rw-r--r--absl/copts/GENERATED_AbseilCopts.cmake6
-rw-r--r--absl/copts/GENERATED_copts.bzl6
-rw-r--r--absl/copts/copts.py8
-rw-r--r--absl/debugging/CMakeLists.txt12
-rw-r--r--absl/debugging/internal/demangle_test.cc5
-rw-r--r--absl/debugging/symbolize_win32.inc6
-rw-r--r--absl/hash/CMakeLists.txt6
-rw-r--r--absl/hash/internal/hash.h2
-rw-r--r--absl/memory/memory_test.cc4
-rw-r--r--absl/meta/CMakeLists.txt2
-rw-r--r--absl/meta/type_traits.h109
-rw-r--r--absl/meta/type_traits_test.cc191
-rw-r--r--absl/numeric/CMakeLists.txt2
-rw-r--r--absl/strings/CMakeLists.txt2
-rw-r--r--absl/strings/escaping.cc22
-rw-r--r--absl/strings/escaping.h12
-rw-r--r--absl/strings/escaping_test.cc3
-rw-r--r--absl/strings/internal/str_format/convert_test.cc9
-rw-r--r--absl/synchronization/CMakeLists.txt2
-rw-r--r--absl/time/internal/cctz/BUILD.bazel23
-rw-r--r--absl/time/internal/cctz/include/cctz/civil_time_detail.h2
-rw-r--r--absl/time/internal/cctz/src/civil_time_test.cc4
-rw-r--r--absl/time/internal/cctz/src/time_zone_lookup.cc4
-rw-r--r--absl/time/time_test.cc2
-rw-r--r--absl/types/any_test.cc68
-rw-r--r--absl/types/variant_test.cc110
-rw-r--r--absl/utility/utility.h26
37 files changed, 694 insertions, 87 deletions
diff --git a/absl/BUILD.bazel b/absl/BUILD.bazel
index 8e3c1773..853330d4 100644
--- a/absl/BUILD.bazel
+++ b/absl/BUILD.bazel
@@ -25,13 +25,18 @@ create_llvm_config(
visibility = [":__subpackages__"],
)
-# following configs are based on mapping defined in: https://git.io/v5Ijz
+config_setting(
+ name = "osx",
+ constraint_values = [
+ "@bazel_tools//platforms:osx",
+ ],
+)
+
config_setting(
name = "ios",
- values = {
- "cpu": "darwin",
- },
- visibility = [":__subpackages__"],
+ constraint_values = [
+ "@bazel_tools//platforms:ios",
+ ],
)
config_setting(
diff --git a/absl/algorithm/CMakeLists.txt b/absl/algorithm/CMakeLists.txt
index c51eb10e..9fbe36f6 100644
--- a/absl/algorithm/CMakeLists.txt
+++ b/absl/algorithm/CMakeLists.txt
@@ -29,6 +29,8 @@ absl_cc_test(
algorithm_test
SRCS
"algorithm_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::algorithm
gmock_main
@@ -53,6 +55,8 @@ absl_cc_test(
container_test
SRCS
"container_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::algorithm_container
absl::base
diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt
index 5042f156..b9f35bc0 100644
--- a/absl/base/CMakeLists.txt
+++ b/absl/base/CMakeLists.txt
@@ -26,6 +26,8 @@ absl_cc_library(
"internal/spinlock_posix.inc"
"internal/spinlock_wait.cc"
"internal/spinlock_win32.inc"
+ COPTS
+ ${ABSL_DEFAULT_COPTS}
DEPS
absl::core_headers
)
@@ -221,6 +223,8 @@ absl_cc_test(
atomic_hook_test
SRCS
"internal/atomic_hook_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::base
absl::core_headers
@@ -232,6 +236,8 @@ absl_cc_test(
bit_cast_test
SRCS
"bit_cast_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::base
absl::core_headers
@@ -243,6 +249,8 @@ absl_cc_test(
throw_delegate_test
SRCS
"throw_delegate_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::base
absl::throw_delegate
@@ -257,6 +265,8 @@ absl_cc_test(
"inline_variable_test.cc"
"inline_variable_test_a.cc"
"inline_variable_test_b.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::base_internal
gtest_main
@@ -267,6 +277,8 @@ absl_cc_test(
invoke_test
SRCS
"invoke_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::base_internal
absl::memory
@@ -297,6 +309,8 @@ absl_cc_test(
spinlock_test
SRCS
"spinlock_test_common.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::base
absl::core_headers
@@ -324,6 +338,8 @@ absl_cc_test(
endian_test
SRCS
"internal/endian_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::base
absl::config
@@ -336,6 +352,8 @@ absl_cc_test(
config_test
SRCS
"config_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::config
absl::synchronization
@@ -347,6 +365,8 @@ absl_cc_test(
call_once_test
SRCS
"call_once_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::base
absl::core_headers
@@ -359,6 +379,8 @@ absl_cc_test(
raw_logging_test
SRCS
"raw_logging_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::base
absl::strings
@@ -370,6 +392,8 @@ absl_cc_test(
sysinfo_test
SRCS
"internal/sysinfo_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::base
absl::synchronization
@@ -381,6 +405,8 @@ absl_cc_test(
low_level_alloc_test
SRCS
"internal/low_level_alloc_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::malloc_internal
Threads::Threads
@@ -391,6 +417,8 @@ absl_cc_test(
thread_identity_test
SRCS
"internal/thread_identity_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::base
absl::core_headers
@@ -415,6 +443,8 @@ absl_cc_test(
bits_test
SRCS
"internal/bits_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::bits
gtest_main
@@ -438,6 +468,8 @@ absl_cc_test(
scoped_set_env_test
SRCS
"internal/scoped_set_env_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::scoped_set_env
gtest_main
@@ -448,6 +480,8 @@ absl_cc_test(
cmake_thread_test
SRCS
"internal/cmake_thread_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::base
)
diff --git a/absl/base/internal/raw_logging.cc b/absl/base/internal/raw_logging.cc
index b5a05e8c..878fe6c6 100644
--- a/absl/base/internal/raw_logging.cc
+++ b/absl/base/internal/raw_logging.cc
@@ -36,7 +36,8 @@
// This preprocessor token is also defined in raw_io.cc. If you need to copy
// this, consider moving both to config.h instead.
#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
- defined(__Fuchsia__) || defined(__native_client__)
+ defined(__Fuchsia__) || defined(__native_client__) || \
+ defined(__EMSCRIPTEN__)
#include <unistd.h>
diff --git a/absl/base/internal/sysinfo_test.cc b/absl/base/internal/sysinfo_test.cc
index 247f3d88..82bbcc2b 100644
--- a/absl/base/internal/sysinfo_test.cc
+++ b/absl/base/internal/sysinfo_test.cc
@@ -37,12 +37,12 @@ TEST(SysinfoTest, NumCPUs) {
}
TEST(SysinfoTest, NominalCPUFrequency) {
-#if !(defined(__aarch64__) && defined(__linux__))
+#if !(defined(__aarch64__) && defined(__linux__)) && !defined(__EMSCRIPTEN__)
EXPECT_GE(NominalCPUFrequency(), 1000.0)
<< "NominalCPUFrequency() did not return a reasonable value";
#else
- // TODO(absl-team): Aarch64 cannot read the CPU frequency from sysfs, so we
- // get back 1.0. Fix once the value is available.
+ // Aarch64 cannot read the CPU frequency from sysfs, so we get back 1.0.
+ // Emscripten does not have a sysfs to read from at all.
EXPECT_EQ(NominalCPUFrequency(), 1.0)
<< "CPU frequency detection was fixed! Please update unittest.";
#endif
diff --git a/absl/base/internal/unscaledcycleclock.h b/absl/base/internal/unscaledcycleclock.h
index 58950cc2..2d361e96 100644
--- a/absl/base/internal/unscaledcycleclock.h
+++ b/absl/base/internal/unscaledcycleclock.h
@@ -59,7 +59,8 @@
// CycleClock that runs at atleast 1 MHz. We've found some Android
// ARM64 devices where this is not the case, so we disable it by
// default on Android ARM64.
-#if defined(__native_client__) || TARGET_OS_IPHONE || \
+#if defined(__native_client__) || \
+ (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || \
(defined(__ANDROID__) && defined(__aarch64__))
#define ABSL_USE_UNSCALED_CYCLECLOCK_DEFAULT 0
#else
diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt
index 3c44bd0e..9531d7f9 100644
--- a/absl/container/CMakeLists.txt
+++ b/absl/container/CMakeLists.txt
@@ -27,7 +27,9 @@ absl_cc_library(
NAME
compressed_tuple
HDRS
- "internal/compressed_tuple.h"
+ "internal/compressed_tuple.h"
+ COPTS
+ ${ABSL_DEFAULT_COPTS}
DEPS
absl::utility
PUBLIC
@@ -38,6 +40,8 @@ absl_cc_test(
compressed_tuple_test
SRCS
"internal/compressed_tuple_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::compressed_tuple
absl::memory
@@ -68,6 +72,7 @@ absl_cc_test(
SRCS
"fixed_array_test.cc"
COPTS
+ ${ABSL_TEST_COPTS}
${ABSL_EXCEPTIONS_FLAG}
LINKOPTS
${ABSL_EXCEPTIONS_FLAG_LINKOPTS}
@@ -84,6 +89,8 @@ absl_cc_test(
fixed_array_test_noexceptions
SRCS
"fixed_array_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::fixed_array
absl::exception_testing
@@ -98,6 +105,7 @@ absl_cc_test(
SRCS
"fixed_array_exception_safety_test.cc"
COPTS
+ ${ABSL_TEST_COPTS}
${ABSL_EXCEPTIONS_FLAG}
LINKOPTS
${ABSL_EXCEPTIONS_FLAG_LINKOPTS}
@@ -151,6 +159,7 @@ absl_cc_test(
SRCS
"inlined_vector_test.cc"
COPTS
+ ${ABSL_TEST_COPTS}
${ABSL_EXCEPTIONS_FLAG}
LINKOPTS
${ABSL_EXCEPTIONS_FLAG_LINKOPTS}
@@ -172,6 +181,8 @@ absl_cc_test(
inlined_vector_test_noexceptions
SRCS
"inlined_vector_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::inlined_vector
absl::test_instance_tracker
@@ -201,6 +212,8 @@ absl_cc_test(
test_instance_tracker_test
SRCS
"internal/test_instance_tracker_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::test_instance_tracker
gmock_main
@@ -227,6 +240,8 @@ absl_cc_test(
flat_hash_map_test
SRCS
"flat_hash_map_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::flat_hash_map
absl::hash_generator_testing
@@ -261,6 +276,7 @@ absl_cc_test(
SRCS
"flat_hash_set_test.cc"
COPTS
+ ${ABSL_TEST_COPTS}
"-DUNORDERED_SET_CXX17"
DEPS
absl::flat_hash_set
@@ -296,6 +312,8 @@ absl_cc_test(
node_hash_map_test
SRCS
"node_hash_map_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::hash_generator_testing
absl::node_hash_map
@@ -329,6 +347,7 @@ absl_cc_test(
SRCS
"node_hash_set_test.cc"
COPTS
+ ${ABSL_TEST_COPTS}
"-DUNORDERED_SET_CXX17"
DEPS
absl::hash_generator_testing
@@ -358,6 +377,8 @@ absl_cc_test(
container_memory_test
SRCS
"internal/container_memory_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::container_memory
absl::strings
@@ -383,6 +404,8 @@ absl_cc_test(
hash_function_defaults_test
SRCS
"internal/hash_function_defaults_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::hash_function_defaults
absl::hash
@@ -424,6 +447,8 @@ absl_cc_test(
hash_policy_testing_test
SRCS
"internal/hash_policy_testing_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::hash_policy_testing
gmock_main
@@ -446,6 +471,8 @@ absl_cc_test(
hash_policy_traits_test
SRCS
"internal/hash_policy_traits_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::hash_policy_traits
gmock_main
@@ -472,6 +499,8 @@ absl_cc_test(
hashtablez_sampler_test
SRCS
"internal/hashtablez_sampler_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::hashtablez_sampler
absl::have_sse
@@ -523,6 +552,8 @@ absl_cc_test(
node_hash_policy_test
SRCS
"internal/node_hash_policy_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::hash_policy_traits
absl::node_hash_policy
@@ -587,6 +618,8 @@ absl_cc_test(
raw_hash_set_test
SRCS
"internal/raw_hash_set_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::container_memory
absl::hash_function_defaults
@@ -604,6 +637,8 @@ absl_cc_test(
raw_hash_set_allocator_test
SRCS
"internal/raw_hash_set_allocator_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::raw_hash_set
absl::tracked
@@ -632,6 +667,8 @@ absl_cc_test(
layout_test
SRCS
"internal/layout_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::layout
absl::base
@@ -765,6 +802,8 @@ absl_cc_test(
unordered_set_test
SRCS
"internal/unordered_set_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::unordered_set_constructor_test
absl::unordered_set_lookup_test
@@ -778,6 +817,8 @@ absl_cc_test(
unordered_map_test
SRCS
"internal/unordered_map_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::unordered_map_constructor_test
absl::unordered_map_lookup_test
diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h
index 978d5033..34e9aa0a 100644
--- a/absl/container/inlined_vector.h
+++ b/absl/container/inlined_vector.h
@@ -174,9 +174,9 @@ class InlinedVector {
// Creates an inlined vector by moving in the contents of an `other` inlined
// vector without performing any allocations. If `other` contains allocated
// memory, the newly-created instance will take ownership of that memory
- // (leaving `other` itself empty). However, if `other` does not contain any
- // allocated memory, the new inlined vector will will perform element-wise
- // move construction of `other`s elements.
+ // (leaving `other` empty). However, if `other` does not contain allocated
+ // memory (i.e. is inlined), the new inlined vector will perform element-wise
+ // move construction of `other`'s elements.
//
// NOTE: since no allocation is performed for the inlined vector in either
// case, the `noexcept(...)` specification depends on whether moving the
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index 9c926812..8ac0dda2 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -1437,15 +1437,15 @@ class raw_hash_set {
void initialize_slots() {
assert(capacity_);
- // Folks with custom allocators often make unwaranted assumptions about the
+ // Folks with custom allocators often make unwarranted assumptions about the
// behavior of their classes vis-a-vis trivial destructability and what
// calls they will or wont make. Avoid sampling for people with custom
- // allocators to get us out of this mess. This is not a hard guarntee but a
- // workaround while we plan the exact guarantee we want to provide.
+ // allocators to get us out of this mess. This is not a hard guarantee but
+ // a workaround while we plan the exact guarantee we want to provide.
//
// People are often sloppy with the exact type of their allocator (sometimes
// it has an extra const or is missing the pair, but rebinds made it work
- // anyway). To avoid the ambiguitity, we work off SlotAlloc which we have
+ // anyway). To avoid the ambiguity, we work off SlotAlloc which we have
// bound more carefully.
if (std::is_same<SlotAlloc, std::allocator<slot_type>>::value &&
slots_ == nullptr) {
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc
index cb845121..ed4ca8c8 100644
--- a/absl/container/internal/raw_hash_set_test.cc
+++ b/absl/container/internal/raw_hash_set_test.cc
@@ -433,9 +433,10 @@ TEST(Table, Prefetch) {
// Do not run in debug mode, when prefetch is not implemented, or when
// sanitizers are enabled, or on WebAssembly.
-#if defined(NDEBUG) && defined(__GNUC__) && !defined(ADDRESS_SANITIZER) && \
- !defined(MEMORY_SANITIZER) && !defined(THREAD_SANITIZER) && \
- !defined(UNDEFINED_BEHAVIOR_SANITIZER) && !defined(__EMSCRIPTEN__)
+#if defined(NDEBUG) && defined(__GNUC__) && defined(__x86_64__) && \
+ !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) && \
+ !defined(THREAD_SANITIZER) && !defined(UNDEFINED_BEHAVIOR_SANITIZER) && \
+ !defined(__EMSCRIPTEN__)
const auto now = [] { return absl::base_internal::CycleClock::Now(); };
// Make size enough to not fit in L2 cache (16.7 Mb)
@@ -1080,7 +1081,7 @@ ProbeStats CollectProbeStatsOnKeysXoredWithSeed(const std::vector<int64_t>& keys
ExpectedStats XorSeedExpectedStats() {
constexpr bool kRandomizesInserts =
-#if NDEBUG
+#ifdef NDEBUG
false;
#else // NDEBUG
true;
@@ -1174,7 +1175,7 @@ ProbeStats CollectProbeStatsOnLinearlyTransformedKeys(
ExpectedStats LinearTransformExpectedStats() {
constexpr bool kRandomizesInserts =
-#if NDEBUG
+#ifdef NDEBUG
false;
#else // NDEBUG
true;
diff --git a/absl/copts/GENERATED_AbseilCopts.cmake b/absl/copts/GENERATED_AbseilCopts.cmake
index 5543638c..27e6f5a0 100644
--- a/absl/copts/GENERATED_AbseilCopts.cmake
+++ b/absl/copts/GENERATED_AbseilCopts.cmake
@@ -37,7 +37,6 @@ list(APPEND ABSL_CLANG_CL_FLAGS
"-Wno-shorten-64-to-32"
"-Wno-switch-enum"
"-Wno-thread-safety-negative"
- "-Wno-undef"
"-Wno-unknown-warning-option"
"-Wno-unreachable-code"
"-Wno-unused-macros"
@@ -62,6 +61,7 @@ list(APPEND ABSL_CLANG_CL_FLAGS
list(APPEND ABSL_CLANG_CL_TEST_FLAGS
"-Wno-c99-extensions"
+ "-Wno-deprecated-declarations"
"-Wno-missing-noreturn"
"-Wno-missing-prototypes"
"-Wno-missing-variable-declarations"
@@ -103,6 +103,7 @@ list(APPEND ABSL_GCC_FLAGS
list(APPEND ABSL_GCC_TEST_FLAGS
"-Wno-conversion-null"
+ "-Wno-deprecated-declarations"
"-Wno-missing-declarations"
"-Wno-sign-compare"
"-Wno-unused-function"
@@ -144,7 +145,6 @@ list(APPEND ABSL_LLVM_FLAGS
"-Wno-shorten-64-to-32"
"-Wno-switch-enum"
"-Wno-thread-safety-negative"
- "-Wno-undef"
"-Wno-unknown-warning-option"
"-Wno-unreachable-code"
"-Wno-unused-macros"
@@ -164,6 +164,7 @@ list(APPEND ABSL_LLVM_FLAGS
list(APPEND ABSL_LLVM_TEST_FLAGS
"-Wno-c99-extensions"
+ "-Wno-deprecated-declarations"
"-Wno-missing-noreturn"
"-Wno-missing-prototypes"
"-Wno-missing-variable-declarations"
@@ -211,5 +212,6 @@ list(APPEND ABSL_MSVC_TEST_FLAGS
"/wd4018"
"/wd4101"
"/wd4503"
+ "/wd4996"
"/DNOMINMAX"
)
diff --git a/absl/copts/GENERATED_copts.bzl b/absl/copts/GENERATED_copts.bzl
index 10caa78a..0feb0f4b 100644
--- a/absl/copts/GENERATED_copts.bzl
+++ b/absl/copts/GENERATED_copts.bzl
@@ -38,7 +38,6 @@ ABSL_CLANG_CL_FLAGS = [
"-Wno-shorten-64-to-32",
"-Wno-switch-enum",
"-Wno-thread-safety-negative",
- "-Wno-undef",
"-Wno-unknown-warning-option",
"-Wno-unreachable-code",
"-Wno-unused-macros",
@@ -63,6 +62,7 @@ ABSL_CLANG_CL_FLAGS = [
ABSL_CLANG_CL_TEST_FLAGS = [
"-Wno-c99-extensions",
+ "-Wno-deprecated-declarations",
"-Wno-missing-noreturn",
"-Wno-missing-prototypes",
"-Wno-missing-variable-declarations",
@@ -104,6 +104,7 @@ ABSL_GCC_FLAGS = [
ABSL_GCC_TEST_FLAGS = [
"-Wno-conversion-null",
+ "-Wno-deprecated-declarations",
"-Wno-missing-declarations",
"-Wno-sign-compare",
"-Wno-unused-function",
@@ -145,7 +146,6 @@ ABSL_LLVM_FLAGS = [
"-Wno-shorten-64-to-32",
"-Wno-switch-enum",
"-Wno-thread-safety-negative",
- "-Wno-undef",
"-Wno-unknown-warning-option",
"-Wno-unreachable-code",
"-Wno-unused-macros",
@@ -165,6 +165,7 @@ ABSL_LLVM_FLAGS = [
ABSL_LLVM_TEST_FLAGS = [
"-Wno-c99-extensions",
+ "-Wno-deprecated-declarations",
"-Wno-missing-noreturn",
"-Wno-missing-prototypes",
"-Wno-missing-variable-declarations",
@@ -212,5 +213,6 @@ ABSL_MSVC_TEST_FLAGS = [
"/wd4018",
"/wd4101",
"/wd4503",
+ "/wd4996",
"/DNOMINMAX",
]
diff --git a/absl/copts/copts.py b/absl/copts/copts.py
index cdcf61d6..154c0ce6 100644
--- a/absl/copts/copts.py
+++ b/absl/copts/copts.py
@@ -65,7 +65,6 @@ LLVM_DISABLE_WARNINGS_FLAGS = [
"-Wno-shorten-64-to-32",
"-Wno-switch-enum",
"-Wno-thread-safety-negative",
- "-Wno-undef",
"-Wno-unknown-warning-option",
"-Wno-unreachable-code",
# Causes warnings on include guards
@@ -89,6 +88,7 @@ LLVM_DISABLE_WARNINGS_FLAGS = [
LLVM_TEST_DISABLE_WARNINGS_FLAGS = [
"-Wno-c99-extensions",
+ "-Wno-deprecated-declarations",
"-Wno-missing-noreturn",
"-Wno-missing-prototypes",
"-Wno-missing-variable-declarations",
@@ -110,7 +110,9 @@ LLVM_TEST_DISABLE_WARNINGS_FLAGS = [
]
MSVC_STYLE_EXCEPTIONS_FLAGS = [
- "/U_HAS_EXCEPTIONS", "/D_HAS_EXCEPTIONS=1", "/EHsc"
+ "/U_HAS_EXCEPTIONS",
+ "/D_HAS_EXCEPTIONS=1",
+ "/EHsc"
]
MSVC_DEFINES = [
@@ -148,6 +150,7 @@ COPT_VARS = {
],
"ABSL_GCC_TEST_FLAGS": [
"-Wno-conversion-null",
+ "-Wno-deprecated-declarations",
"-Wno-missing-declarations",
"-Wno-sign-compare",
"-Wno-unused-function",
@@ -183,6 +186,7 @@ COPT_VARS = {
"/wd4018", # signed/unsigned mismatch
"/wd4101", # unreferenced local variable
"/wd4503", # decorated name length exceeded, name was truncated
+ "/wd4996", # use of deprecated symbol
"/DNOMINMAX", # disable the min() and max() macros from <windows.h>
],
"ABSL_MSVC_EXCEPTIONS_FLAGS":
diff --git a/absl/debugging/CMakeLists.txt b/absl/debugging/CMakeLists.txt
index dccd4a56..d813fede 100644
--- a/absl/debugging/CMakeLists.txt
+++ b/absl/debugging/CMakeLists.txt
@@ -43,6 +43,8 @@ absl_cc_library(
"symbolize_win32.inc"
COPTS
${ABSL_DEFAULT_COPTS}
+ LINKOPTS
+ ${ABSL_DEFAULT_LINKOPTS}
DEPS
absl::debugging_internal
absl::demangle_internal
@@ -196,6 +198,8 @@ absl_cc_library(
leak_check_disable
SRCS
"leak_check_disable.cc"
+ COPTS
+ ${ABSL_DEFAULT_COPTS}
PUBLIC
)
@@ -207,6 +211,7 @@ absl_cc_library(
SRCS
"leak_check.cc"
COPTS
+ ${ABSL_DEFAULT_COPTS}
$<$<BOOL:${ABSL_HAVE_LSAN}>:-DLEAK_SANITIZER>
TESTONLY
)
@@ -219,6 +224,7 @@ absl_cc_library(
SRCS
"leak_check.cc"
COPTS
+ ${ABSL_DEFAULT_COPTS}
"-ULEAK_SANITIZER"
TESTONLY
)
@@ -229,6 +235,7 @@ absl_cc_test(
SRCS
"leak_check_test.cc"
COPTS
+ ${ABSL_DEFAULT_COPTS}
"$<$<BOOL:${ABSL_HAVE_LSAN}>:-DABSL_EXPECT_LEAK_SANITIZER>"
LINKOPTS
"${ABSL_LSAN_LINKOPTS}"
@@ -244,6 +251,7 @@ absl_cc_test(
SRCS
"leak_check_test.cc"
COPTS
+ ${ABSL_TEST_COPTS}
"-UABSL_EXPECT_LEAK_SANITIZER"
DEPS
absl::leak_check_api_disabled_for_testing
@@ -256,6 +264,8 @@ absl_cc_test(
disabled_leak_check_test
SRCS
"leak_check_fail_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
LINKOPTS
"${ABSL_LSAN_LINKOPTS}"
DEPS
@@ -298,6 +308,8 @@ absl_cc_test(
absl_cc_library(
NAME
debugging
+ COPTS
+ ${ABSL_DEFAULT_COPTS}
DEPS
absl::stacktrace
absl::leak_check
diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc
index 883b92db..a68ce324 100644
--- a/absl/debugging/internal/demangle_test.cc
+++ b/absl/debugging/internal/demangle_test.cc
@@ -81,8 +81,9 @@ TEST(Demangle, Clones) {
// Tests that verify that Demangle footprint is within some limit.
// They are not to be run under sanitizers as the sanitizers increase
// stack consumption by about 4x.
-#if defined(ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION) && \
- !ADDRESS_SANITIZER && !MEMORY_SANITIZER && !THREAD_SANITIZER
+#if defined(ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION) && \
+ !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) && \
+ !defined(THREAD_SANITIZER)
static const char *g_mangled;
static char g_demangle_buffer[4096];
diff --git a/absl/debugging/symbolize_win32.inc b/absl/debugging/symbolize_win32.inc
index 17ea618a..7ed3bd3a 100644
--- a/absl/debugging/symbolize_win32.inc
+++ b/absl/debugging/symbolize_win32.inc
@@ -16,7 +16,13 @@
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680578(v=vs.85).aspx
#include <windows.h>
+
+// MSVC header DbgHelp.h has a warning for an ignored typedef.
+#pragma warning(push)
+#pragma warning(disable:4091)
#include <DbgHelp.h>
+#pragma warning(pop)
+
#pragma comment(lib, "DbgHelp")
#include <algorithm>
diff --git a/absl/hash/CMakeLists.txt b/absl/hash/CMakeLists.txt
index 4cafc133..febc551f 100644
--- a/absl/hash/CMakeLists.txt
+++ b/absl/hash/CMakeLists.txt
@@ -43,6 +43,8 @@ absl_cc_library(
hash_testing
HDRS
"hash_testing.h"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::spy_hash_state
absl::meta
@@ -56,7 +58,9 @@ absl_cc_test(
NAME
hash_test
SRCS
- "hash_test.cc"
+ "hash_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
DEPS
absl::hash
absl::hash_testing
diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h
index 9ab98901..18665173 100644
--- a/absl/hash/internal/hash.h
+++ b/absl/hash/internal/hash.h
@@ -615,7 +615,7 @@ struct HashSelect {
public:
// Probe each implementation in order.
- // disjunction provides short circuting wrt instantiation.
+ // disjunction provides short circuiting wrt instantiation.
template <typename T>
using Apply = absl::disjunction< //
Probe<UniquelyRepresentedProbe, T>, //
diff --git a/absl/memory/memory_test.cc b/absl/memory/memory_test.cc
index 8905433c..c47820e5 100644
--- a/absl/memory/memory_test.cc
+++ b/absl/memory/memory_test.cc
@@ -620,7 +620,7 @@ TEST(AllocatorTraits, FunctionsFull) {
}
TEST(AllocatorNoThrowTest, DefaultAllocator) {
-#if ABSL_ALLOCATOR_NOTHROW
+#if defined(ABSL_ALLOCATOR_NOTHROW) && ABSL_ALLOCATOR_NOTHROW
EXPECT_TRUE(absl::default_allocator_is_nothrow::value);
#else
EXPECT_FALSE(absl::default_allocator_is_nothrow::value);
@@ -628,7 +628,7 @@ TEST(AllocatorNoThrowTest, DefaultAllocator) {
}
TEST(AllocatorNoThrowTest, StdAllocator) {
-#if ABSL_ALLOCATOR_NOTHROW
+#if defined(ABSL_ALLOCATOR_NOTHROW) && ABSL_ALLOCATOR_NOTHROW
EXPECT_TRUE(absl::allocator_is_nothrow<std::allocator<int>>::value);
#else
EXPECT_FALSE(absl::allocator_is_nothrow<std::allocator<int>>::value);
diff --git a/absl/meta/CMakeLists.txt b/absl/meta/CMakeLists.txt
index f866e54e..672ead2f 100644
--- a/absl/meta/CMakeLists.txt
+++ b/absl/meta/CMakeLists.txt
@@ -42,6 +42,8 @@ absl_cc_test(
absl_cc_library(
NAME
meta
+ COPTS
+ ${ABSL_DEFAULT_COPTS}
DEPS
absl::type_traits
PUBLIC
diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h
index a8068e31..c08e3754 100644
--- a/absl/meta/type_traits.h
+++ b/absl/meta/type_traits.h
@@ -43,8 +43,39 @@
namespace absl {
+// Defined and documented later on in this file.
+template <typename T>
+struct is_trivially_move_assignable;
+
namespace type_traits_internal {
+// Silence MSVC warnings about the destructor being defined as deleted.
+#if defined(_MSC_VER) && !defined(__GNUC__)
+#pragma warning(push)
+#pragma warning(disable : 4624)
+#endif // defined(_MSC_VER) && !defined(__GNUC__)
+
+template <class T>
+union SingleMemberUnion {
+ T t;
+};
+
+// Restore the state of the destructor warning that was silenced above.
+#if defined(_MSC_VER) && !defined(__GNUC__)
+#pragma warning(pop)
+#endif // defined(_MSC_VER) && !defined(__GNUC__)
+
+template <class T>
+struct IsTriviallyMoveAssignableReference : std::false_type {};
+
+template <class T>
+struct IsTriviallyMoveAssignableReference<T&>
+ : absl::is_trivially_move_assignable<T>::type {};
+
+template <class T>
+struct IsTriviallyMoveAssignableReference<T&&>
+ : absl::is_trivially_move_assignable<T>::type {};
+
template <typename... Ts>
struct VoidTImpl {
using type = void;
@@ -275,6 +306,40 @@ struct is_trivially_default_constructible
#endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
};
+// is_trivially_move_constructible()
+//
+// Determines whether the passed type `T` is trivially move constructible.
+//
+// This metafunction is designed to be a drop-in replacement for the C++11
+// `std::is_trivially_move_constructible()` metafunction for platforms that have
+// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do
+// fully support C++11, we check whether this yields the same result as the std
+// implementation.
+//
+// NOTE: `T obj(declval<T>());` needs to be well-formed and not call any
+// nontrivial operation. Nontrivially destructible types will cause the
+// expression to be nontrivial.
+template <typename T>
+struct is_trivially_move_constructible
+ : std::conditional<
+ std::is_object<T>::value && !std::is_array<T>::value,
+ std::is_move_constructible<
+ type_traits_internal::SingleMemberUnion<T>>,
+ std::is_reference<T>>::type::type {
+#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
+ private:
+ static constexpr bool compliant =
+ std::is_trivially_move_constructible<T>::value ==
+ is_trivially_move_constructible::value;
+ static_assert(compliant || std::is_trivially_move_constructible<T>::value,
+ "Not compliant with std::is_trivially_move_constructible; "
+ "Standard: false, Implementation: true");
+ static_assert(compliant || !std::is_trivially_move_constructible<T>::value,
+ "Not compliant with std::is_trivially_move_constructible; "
+ "Standard: true, Implementation: false");
+#endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
+};
+
// is_trivially_copy_constructible()
//
// Determines whether the passed type `T` is trivially copy constructible.
@@ -290,9 +355,11 @@ struct is_trivially_default_constructible
// expression to be nontrivial.
template <typename T>
struct is_trivially_copy_constructible
- : std::integral_constant<bool, __has_trivial_copy(T) &&
- std::is_copy_constructible<T>::value &&
- is_trivially_destructible<T>::value> {
+ : std::conditional<
+ std::is_object<T>::value && !std::is_array<T>::value,
+ std::is_copy_constructible<
+ type_traits_internal::SingleMemberUnion<T>>,
+ std::is_lvalue_reference<T>>::type::type {
#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
private:
static constexpr bool compliant =
@@ -307,6 +374,42 @@ struct is_trivially_copy_constructible
#endif // ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
};
+// is_trivially_move_assignable()
+//
+// Determines whether the passed type `T` is trivially move assignable.
+//
+// This metafunction is designed to be a drop-in replacement for the C++11
+// `std::is_trivially_move_assignable()` metafunction for platforms that have
+// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do
+// fully support C++11, we check whether this yields the same result as the std
+// implementation.
+//
+// NOTE: `is_assignable<T, U>::value` is `true` if the expression
+// `declval<T>() = declval<U>()` is well-formed when treated as an unevaluated
+// operand. `is_trivially_assignable<T, U>` requires the assignment to call no
+// operation that is not trivial. `is_trivially_copy_assignable<T>` is simply
+// `is_trivially_assignable<T&, T>`.
+template <typename T>
+struct is_trivially_move_assignable
+ : std::conditional<
+ std::is_object<T>::value && !std::is_array<T>::value,
+ std::is_move_assignable<type_traits_internal::SingleMemberUnion<T>>,
+ type_traits_internal::IsTriviallyMoveAssignableReference<T>>::type::
+ type {
+#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
+ private:
+ static constexpr bool compliant =
+ std::is_trivially_move_assignable<T>::value ==
+ is_trivially_move_assignable::value;
+ static_assert(compliant || std::is_trivially_move_assignable<T>::value,
+ "Not compliant with std::is_trivially_move_assignable; "
+ "Standard: false, Implementation: true");
+ static_assert(compliant || !std::is_trivially_move_assignable<T>::value,
+ "Not compliant with std::is_trivially_move_assignable; "
+ "Standard: true, Implementation: false");
+#endif // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
+};
+
// is_trivially_copy_assignable()
//
// Determines whether the passed type `T` is trivially copy assignable.
diff --git a/absl/meta/type_traits_test.cc b/absl/meta/type_traits_test.cc
index d3ead6d0..82b1be51 100644
--- a/absl/meta/type_traits_test.cc
+++ b/absl/meta/type_traits_test.cc
@@ -214,6 +214,29 @@ class DeletedDefaultCtor {
int n_;
};
+class TrivialMoveCtor {
+ public:
+ explicit TrivialMoveCtor(int n) : n_(n) {}
+ TrivialMoveCtor(TrivialMoveCtor&&) = default;
+ TrivialMoveCtor& operator=(const TrivialMoveCtor& t) {
+ n_ = t.n_;
+ return *this;
+ }
+
+ private:
+ int n_;
+};
+
+class NontrivialMoveCtor {
+ public:
+ explicit NontrivialMoveCtor(int n) : n_(n) {}
+ NontrivialMoveCtor(NontrivialMoveCtor&& t) noexcept : n_(t.n_) {}
+ NontrivialMoveCtor& operator=(const NontrivialMoveCtor&) = default;
+
+ private:
+ int n_;
+};
+
class TrivialCopyCtor {
public:
explicit TrivialCopyCtor(int n) : n_(n) {}
@@ -247,6 +270,29 @@ class DeletedCopyCtor {
int n_;
};
+class TrivialMoveAssign {
+ public:
+ explicit TrivialMoveAssign(int n) : n_(n) {}
+ TrivialMoveAssign(const TrivialMoveAssign& t) : n_(t.n_) {}
+ TrivialMoveAssign& operator=(TrivialMoveAssign&&) = default;
+ ~TrivialMoveAssign() {} // can have nontrivial destructor
+ private:
+ int n_;
+};
+
+class NontrivialMoveAssign {
+ public:
+ explicit NontrivialMoveAssign(int n) : n_(n) {}
+ NontrivialMoveAssign(const NontrivialMoveAssign&) = default;
+ NontrivialMoveAssign& operator=(NontrivialMoveAssign&& t) noexcept {
+ n_ = t.n_;
+ return *this;
+ }
+
+ private:
+ int n_;
+};
+
class TrivialCopyAssign {
public:
explicit TrivialCopyAssign(int n) : n_(n) {}
@@ -484,6 +530,79 @@ TEST(TypeTraitsTest, TestTrivialDefaultCtor) {
#endif
}
+TEST(TypeTraitsTest, TestTrivialMoveCtor) {
+ // Verify that arithmetic types and pointers have trivial move
+ // constructors.
+ EXPECT_TRUE(absl::is_trivially_move_constructible<bool>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<char>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<unsigned char>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<signed char>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<wchar_t>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<int>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<unsigned int>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<int16_t>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<uint16_t>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<int64_t>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<uint64_t>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<float>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<double>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<long double>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<std::string*>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<Trivial*>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<const std::string*>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<const Trivial*>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<std::string**>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<Trivial**>::value);
+
+ // Reference types
+ EXPECT_TRUE(absl::is_trivially_move_constructible<int&>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<int&&>::value);
+
+ // types with compiler generated move ctors
+ EXPECT_TRUE(absl::is_trivially_move_constructible<Trivial>::value);
+ EXPECT_TRUE(absl::is_trivially_move_constructible<TrivialMoveCtor>::value);
+
+ // Verify that types without them (i.e. nontrivial or deleted) are not.
+ EXPECT_FALSE(
+ absl::is_trivially_move_constructible<NontrivialCopyCtor>::value);
+ EXPECT_FALSE(absl::is_trivially_move_constructible<DeletedCopyCtor>::value);
+ EXPECT_FALSE(
+ absl::is_trivially_move_constructible<NonCopyableOrMovable>::value);
+
+#ifdef ABSL_TRIVIALLY_CONSTRUCTIBLE_VERIFY_TRIVIALLY_DESTRUCTIBLE
+ // type with nontrivial destructor are nontrivial move construbtible
+ EXPECT_FALSE(
+ absl::is_trivially_move_constructible<NontrivialDestructor>::value);
+#endif
+
+ // types with vtables
+ EXPECT_FALSE(absl::is_trivially_move_constructible<Base>::value);
+
+ // Verify that simple_pair of such types is trivially move constructible
+ EXPECT_TRUE(
+ (absl::is_trivially_move_constructible<simple_pair<int, char*>>::value));
+ EXPECT_TRUE((
+ absl::is_trivially_move_constructible<simple_pair<int, Trivial>>::value));
+ EXPECT_TRUE((absl::is_trivially_move_constructible<
+ simple_pair<int, TrivialMoveCtor>>::value));
+
+ // Verify that types without trivial move constructors are
+ // correctly marked as such.
+ EXPECT_FALSE(absl::is_trivially_move_constructible<std::string>::value);
+ EXPECT_FALSE(absl::is_trivially_move_constructible<std::vector<int>>::value);
+
+ // Verify that simple_pairs of types without trivial move constructors
+ // are not marked as trivial.
+ EXPECT_FALSE((absl::is_trivially_move_constructible<
+ simple_pair<int, std::string>>::value));
+ EXPECT_FALSE((absl::is_trivially_move_constructible<
+ simple_pair<std::string, int>>::value));
+
+ // Verify that arrays are not
+ using int10 = int[10];
+ EXPECT_FALSE(absl::is_trivially_move_constructible<int10>::value);
+}
+
TEST(TypeTraitsTest, TestTrivialCopyCtor) {
// Verify that arithmetic types and pointers have trivial copy
// constructors.
@@ -508,6 +627,10 @@ TEST(TypeTraitsTest, TestTrivialCopyCtor) {
EXPECT_TRUE(absl::is_trivially_copy_constructible<std::string**>::value);
EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial**>::value);
+ // Reference types
+ EXPECT_TRUE(absl::is_trivially_copy_constructible<int&>::value);
+ EXPECT_FALSE(absl::is_trivially_copy_constructible<int&&>::value);
+
// types with compiler generated copy ctors
EXPECT_TRUE(absl::is_trivially_copy_constructible<Trivial>::value);
EXPECT_TRUE(absl::is_trivially_copy_constructible<TrivialCopyCtor>::value);
@@ -555,6 +678,74 @@ TEST(TypeTraitsTest, TestTrivialCopyCtor) {
EXPECT_FALSE(absl::is_trivially_copy_constructible<int10>::value);
}
+TEST(TypeTraitsTest, TestTrivialMoveAssign) {
+ // Verify that arithmetic types and pointers have trivial move
+ // assignment operators.
+ EXPECT_TRUE(absl::is_trivially_move_assignable<bool>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<char>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<unsigned char>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<signed char>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<wchar_t>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<int>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<unsigned int>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<int16_t>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<uint16_t>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<int64_t>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<uint64_t>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<float>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<double>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<long double>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<std::string*>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<Trivial*>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<const std::string*>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<const Trivial*>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<std::string**>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<Trivial**>::value);
+
+ // const qualified types are not assignable
+ EXPECT_FALSE(absl::is_trivially_move_assignable<const int>::value);
+
+ // types with compiler generated move assignment
+ EXPECT_TRUE(absl::is_trivially_move_assignable<Trivial>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<TrivialMoveAssign>::value);
+
+ // Verify that types without them (i.e. nontrivial or deleted) are not.
+ EXPECT_FALSE(absl::is_trivially_move_assignable<NontrivialCopyAssign>::value);
+ EXPECT_FALSE(absl::is_trivially_move_assignable<DeletedCopyAssign>::value);
+ EXPECT_FALSE(absl::is_trivially_move_assignable<NonCopyableOrMovable>::value);
+
+ // types with vtables
+ EXPECT_FALSE(absl::is_trivially_move_assignable<Base>::value);
+
+ // Verify that simple_pair is trivially assignable
+ EXPECT_TRUE(
+ (absl::is_trivially_move_assignable<simple_pair<int, char*>>::value));
+ EXPECT_TRUE(
+ (absl::is_trivially_move_assignable<simple_pair<int, Trivial>>::value));
+ EXPECT_TRUE((absl::is_trivially_move_assignable<
+ simple_pair<int, TrivialMoveAssign>>::value));
+
+ // Verify that types not trivially move assignable are
+ // correctly marked as such.
+ EXPECT_FALSE(absl::is_trivially_move_assignable<std::string>::value);
+ EXPECT_FALSE(absl::is_trivially_move_assignable<std::vector<int>>::value);
+
+ // Verify that simple_pairs of types not trivially move assignable
+ // are not marked as trivial.
+ EXPECT_FALSE((absl::is_trivially_move_assignable<
+ simple_pair<int, std::string>>::value));
+ EXPECT_FALSE((absl::is_trivially_move_assignable<
+ simple_pair<std::string, int>>::value));
+
+ // Verify that arrays are not trivially move assignable
+ using int10 = int[10];
+ EXPECT_FALSE(absl::is_trivially_move_assignable<int10>::value);
+
+ // Verify that references are handled correctly
+ EXPECT_TRUE(absl::is_trivially_move_assignable<Trivial&&>::value);
+ EXPECT_TRUE(absl::is_trivially_move_assignable<Trivial&>::value);
+}
+
TEST(TypeTraitsTest, TestTrivialCopyAssign) {
// Verify that arithmetic types and pointers have trivial copy
// assignment operators.
diff --git a/absl/numeric/CMakeLists.txt b/absl/numeric/CMakeLists.txt
index d26141c7..242889f0 100644
--- a/absl/numeric/CMakeLists.txt
+++ b/absl/numeric/CMakeLists.txt
@@ -52,6 +52,8 @@ absl_cc_test(
absl_cc_library(
NAME
numeric
+ COPTS
+ ${ABSL_DEFAULT_COPTS}
DEPS
absl::int128
PUBLIC
diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt
index d3393a39..8515ec2b 100644
--- a/absl/strings/CMakeLists.txt
+++ b/absl/strings/CMakeLists.txt
@@ -501,6 +501,8 @@ absl_cc_library(
"internal/pow10_helper.h"
SRCS
"internal/pow10_helper.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
TESTONLY
)
diff --git a/absl/strings/escaping.cc b/absl/strings/escaping.cc
index bc8307e1..0d336e3f 100644
--- a/absl/strings/escaping.cc
+++ b/absl/strings/escaping.cc
@@ -1055,10 +1055,10 @@ std::string Utf8SafeCHexEscape(absl::string_view src) {
}
// ----------------------------------------------------------------------
-// ptrdiff_t Base64Unescape() - base64 decoder
-// ptrdiff_t Base64Escape() - base64 encoder
-// ptrdiff_t WebSafeBase64Unescape() - Google's variation of base64 decoder
-// ptrdiff_t WebSafeBase64Escape() - Google's variation of base64 encoder
+// Base64Unescape() - base64 decoder
+// Base64Escape() - base64 encoder
+// WebSafeBase64Unescape() - Google's variation of base64 decoder
+// WebSafeBase64Escape() - Google's variation of base64 encoder
//
// Check out
// http://tools.ietf.org/html/rfc2045 for formal description, but what we
@@ -1096,6 +1096,20 @@ void WebSafeBase64Escape(absl::string_view src, std::string* dest) {
src.size(), dest, false, kWebSafeBase64Chars);
}
+std::string Base64Escape(absl::string_view src) {
+ std::string dest;
+ Base64EscapeInternal(reinterpret_cast<const unsigned char*>(src.data()),
+ src.size(), &dest, true, kBase64Chars);
+ return dest;
+}
+
+std::string WebSafeBase64Escape(absl::string_view src) {
+ std::string dest;
+ Base64EscapeInternal(reinterpret_cast<const unsigned char*>(src.data()),
+ src.size(), &dest, false, kWebSafeBase64Chars);
+ return dest;
+}
+
std::string HexStringToBytes(absl::string_view from) {
std::string result;
const auto num = from.size() / 2;
diff --git a/absl/strings/escaping.h b/absl/strings/escaping.h
index fd9be786..198b9348 100644
--- a/absl/strings/escaping.h
+++ b/absl/strings/escaping.h
@@ -132,16 +132,18 @@ bool WebSafeBase64Unescape(absl::string_view src, std::string* dest);
// Base64Escape()
//
-// Encodes a `src` string into a `dest` buffer using base64 encoding, with
-// padding characters. This function conforms with RFC 4648 section 4 (base64).
+// Encodes a `src` string into a base64-encoded string, with padding characters.
+// This function conforms with RFC 4648 section 4 (base64).
void Base64Escape(absl::string_view src, std::string* dest);
+std::string Base64Escape(absl::string_view src);
// WebSafeBase64Escape()
//
-// Encodes a `src` string into a `dest` buffer using '-' instead of '+' and
-// '_' instead of '/', and without padding. This function conforms with RFC 4648
-// section 5 (base64url).
+// Encodes a `src` string into a base64-like string, using '-' instead of '+'
+// and '_' instead of '/', and without padding. This function conforms with RFC
+// 4648 section 5 (base64url).
void WebSafeBase64Escape(absl::string_view src, std::string* dest);
+std::string WebSafeBase64Escape(absl::string_view src);
// HexStringToBytes()
//
diff --git a/absl/strings/escaping_test.cc b/absl/strings/escaping_test.cc
index d433b4c5..6a633cdc 100644
--- a/absl/strings/escaping_test.cc
+++ b/absl/strings/escaping_test.cc
@@ -556,6 +556,7 @@ void TestEscapeAndUnescape() {
StringType encoded("this junk should be ignored");
absl::Base64Escape(tc.plaintext, &encoded);
EXPECT_EQ(encoded, tc.cyphertext);
+ EXPECT_EQ(absl::Base64Escape(tc.plaintext), tc.cyphertext);
StringType decoded("this junk should be ignored");
EXPECT_TRUE(absl::Base64Unescape(encoded, &decoded));
@@ -574,6 +575,7 @@ void TestEscapeAndUnescape() {
encoded = "this junk should be ignored";
absl::WebSafeBase64Escape(tc.plaintext, &encoded);
EXPECT_EQ(encoded, websafe);
+ EXPECT_EQ(absl::WebSafeBase64Escape(tc.plaintext), websafe);
// Let's try the std::string version of the decoder
decoded = "this junk should be ignored";
@@ -586,6 +588,7 @@ void TestEscapeAndUnescape() {
StringType buffer;
absl::WebSafeBase64Escape(tc.plaintext, &buffer);
EXPECT_EQ(tc.cyphertext, buffer);
+ EXPECT_EQ(absl::WebSafeBase64Escape(tc.plaintext), tc.cyphertext);
}
// Verify the behavior when decoding bad data
diff --git a/absl/strings/internal/str_format/convert_test.cc b/absl/strings/internal/str_format/convert_test.cc
index 99cc0afe..3b4d4b0c 100644
--- a/absl/strings/internal/str_format/convert_test.cc
+++ b/absl/strings/internal/str_format/convert_test.cc
@@ -1,6 +1,7 @@
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
+#include <cctype>
#include <cmath>
#include <string>
@@ -32,7 +33,9 @@ std::string LengthModFor(long long) { return "ll"; } // NOLINT
std::string LengthModFor(unsigned long long) { return "ll"; } // NOLINT
std::string EscCharImpl(int v) {
- if (isprint(v)) return std::string(1, static_cast<char>(v));
+ if (std::isprint(static_cast<unsigned char>(v))) {
+ return std::string(1, static_cast<char>(v));
+ }
char buf[64];
int n = snprintf(buf, sizeof(buf), "\\%#.2x",
static_cast<unsigned>(v & 0xff));
@@ -155,7 +158,7 @@ TEST_F(FormatConvertTest, StringPrecision) {
}
TEST_F(FormatConvertTest, Pointer) {
-#if _MSC_VER
+#ifdef _MSC_VER
// MSVC's printf implementation prints pointers differently. We can't easily
// compare our implementation to theirs.
return;
@@ -390,7 +393,7 @@ TEST_F(FormatConvertTest, Uint128) {
}
TEST_F(FormatConvertTest, Float) {
-#if _MSC_VER
+#ifdef _MSC_VER
// MSVC has a different rounding policy than us so we can't test our
// implementation against the native one there.
return;
diff --git a/absl/synchronization/CMakeLists.txt b/absl/synchronization/CMakeLists.txt
index 9156f5ad..6fdbcb28 100644
--- a/absl/synchronization/CMakeLists.txt
+++ b/absl/synchronization/CMakeLists.txt
@@ -113,6 +113,8 @@ absl_cc_library(
thread_pool
HDRS
"internal/thread_pool.h"
+ COPTS
+ ${ABSL_DEFAULT_COPTS}
DEPS
absl::synchronization
absl::core_headers
diff --git a/absl/time/internal/cctz/BUILD.bazel b/absl/time/internal/cctz/BUILD.bazel
index 05f56bca..b05c2347 100644
--- a/absl/time/internal/cctz/BUILD.bazel
+++ b/absl/time/internal/cctz/BUILD.bazel
@@ -16,6 +16,20 @@ package(features = ["-parse_headers"])
licenses(["notice"]) # Apache License
+config_setting(
+ name = "osx",
+ constraint_values = [
+ "@bazel_tools//platforms:osx",
+ ],
+)
+
+config_setting(
+ name = "ios",
+ constraint_values = [
+ "@bazel_tools//platforms:ios",
+ ],
+)
+
### libraries
cc_library(
@@ -62,6 +76,15 @@ cc_library(
"include/cctz/time_zone.h",
"include/cctz/zone_info_source.h",
],
+ linkopts = select({
+ ":osx": [
+ "-framework Foundation",
+ ],
+ ":ios": [
+ "-framework Foundation",
+ ],
+ "//conditions:default": [],
+ }),
visibility = ["//visibility:public"],
deps = [":civil_time"],
)
diff --git a/absl/time/internal/cctz/include/cctz/civil_time_detail.h b/absl/time/internal/cctz/include/cctz/civil_time_detail.h
index a5923f13..bb191b3f 100644
--- a/absl/time/internal/cctz/include/cctz/civil_time_detail.h
+++ b/absl/time/internal/cctz/include/cctz/civil_time_detail.h
@@ -21,7 +21,7 @@
#include <type_traits>
// Disable constexpr support unless we are in C++14 mode.
-#if __cpp_constexpr >= 201304 || _MSC_VER >= 1910
+#if __cpp_constexpr >= 201304 || (defined(_MSC_VER) && _MSC_VER >= 1910)
#define CONSTEXPR_D constexpr // data
#define CONSTEXPR_F constexpr // function
#define CONSTEXPR_M constexpr // member
diff --git a/absl/time/internal/cctz/src/civil_time_test.cc b/absl/time/internal/cctz/src/civil_time_test.cc
index e590ee30..dc7e5a1d 100644
--- a/absl/time/internal/cctz/src/civil_time_test.cc
+++ b/absl/time/internal/cctz/src/civil_time_test.cc
@@ -37,7 +37,7 @@ std::string Format(const T& t) {
} // namespace
-#if __cpp_constexpr >= 201304 || _MSC_VER >= 1910
+#if __cpp_constexpr >= 201304 || (defined(_MSC_VER) && _MSC_VER >= 1910)
// Construction constexpr tests
TEST(CivilTime, Normal) {
@@ -319,7 +319,7 @@ TEST(CivilTime, YearDay) {
constexpr int yd = get_yearday(cd);
static_assert(yd == 28, "YearDay");
}
-#endif // __cpp_constexpr >= 201304 || _MSC_VER >= 1910
+#endif // __cpp_constexpr >= 201304 || (defined(_MSC_VER) && _MSC_VER >= 1910)
// The remaining tests do not use constexpr.
diff --git a/absl/time/internal/cctz/src/time_zone_lookup.cc b/absl/time/internal/cctz/src/time_zone_lookup.cc
index a27bfc13..3c53dd1a 100644
--- a/absl/time/internal/cctz/src/time_zone_lookup.cc
+++ b/absl/time/internal/cctz/src/time_zone_lookup.cc
@@ -16,7 +16,7 @@
#if defined(__ANDROID__)
#include <sys/system_properties.h>
-#if __ANDROID_API__ >= 21
+#if defined(__ANDROID_API__) && __ANDROID_API__ >= 21
#include <dlfcn.h>
#endif
#endif
@@ -37,7 +37,7 @@ namespace absl {
namespace time_internal {
namespace cctz {
-#if defined(__ANDROID__) && __ANDROID_API__ >= 21
+#if defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ >= 21
namespace {
// Android 'L' removes __system_property_get() from the NDK, however
// it is still a hidden symbol in libc so we use dlsym() to access it.
diff --git a/absl/time/time_test.cc b/absl/time/time_test.cc
index 74148d58..4d791f4d 100644
--- a/absl/time/time_test.cc
+++ b/absl/time/time_test.cc
@@ -28,7 +28,7 @@
namespace {
-#if GTEST_USES_SIMPLE_RE
+#if defined(GTEST_USES_SIMPLE_RE) && GTEST_USES_SIMPLE_RE
const char kZoneAbbrRE[] = ".*"; // just punt
#else
const char kZoneAbbrRE[] = "[A-Za-z]{3,4}|[-+][0-9]{2}([0-9]{2})?";
diff --git a/absl/types/any_test.cc b/absl/types/any_test.cc
index a6351bf9..87104721 100644
--- a/absl/types/any_test.cc
+++ b/absl/types/any_test.cc
@@ -154,6 +154,14 @@ TEST(AnyTest, InPlaceConstruction) {
EXPECT_EQ(5, v.value);
}
+TEST(AnyTest, InPlaceConstructionVariableTemplate) {
+ const CopyOnly copy_only{};
+ absl::any o(absl::in_place_type<IntMoveOnlyCopyOnly>, 5, MoveOnly(),
+ copy_only);
+ auto& v = absl::any_cast<IntMoveOnlyCopyOnly&>(o);
+ EXPECT_EQ(5, v.value);
+}
+
TEST(AnyTest, InPlaceConstructionWithCV) {
const CopyOnly copy_only{};
absl::any o(absl::in_place_type_t<const volatile IntMoveOnlyCopyOnly>(), 5,
@@ -162,12 +170,26 @@ TEST(AnyTest, InPlaceConstructionWithCV) {
EXPECT_EQ(5, v.value);
}
+TEST(AnyTest, InPlaceConstructionWithCVVariableTemplate) {
+ const CopyOnly copy_only{};
+ absl::any o(absl::in_place_type<const volatile IntMoveOnlyCopyOnly>, 5,
+ MoveOnly(), copy_only);
+ auto& v = absl::any_cast<IntMoveOnlyCopyOnly&>(o);
+ EXPECT_EQ(5, v.value);
+}
+
TEST(AnyTest, InPlaceConstructionWithFunction) {
absl::any o(absl::in_place_type_t<FunctionType>(), FunctionToEmplace);
FunctionType*& construction_result = absl::any_cast<FunctionType*&>(o);
EXPECT_EQ(&FunctionToEmplace, construction_result);
}
+TEST(AnyTest, InPlaceConstructionWithFunctionVariableTemplate) {
+ absl::any o(absl::in_place_type<FunctionType>, FunctionToEmplace);
+ auto& construction_result = absl::any_cast<FunctionType*&>(o);
+ EXPECT_EQ(&FunctionToEmplace, construction_result);
+}
+
TEST(AnyTest, InPlaceConstructionWithArray) {
ArrayType ar = {5, 42};
absl::any o(absl::in_place_type_t<ArrayType>(), ar);
@@ -175,6 +197,13 @@ TEST(AnyTest, InPlaceConstructionWithArray) {
EXPECT_EQ(&ar[0], construction_result);
}
+TEST(AnyTest, InPlaceConstructionWithArrayVariableTemplate) {
+ ArrayType ar = {5, 42};
+ absl::any o(absl::in_place_type<ArrayType>, ar);
+ auto& construction_result = absl::any_cast<DecayedArray&>(o);
+ EXPECT_EQ(&ar[0], construction_result);
+}
+
TEST(AnyTest, InPlaceConstructionIlist) {
const CopyOnly copy_only{};
absl::any o(absl::in_place_type_t<ListMoveOnlyCopyOnly>(), {1, 2, 3, 4},
@@ -184,6 +213,15 @@ TEST(AnyTest, InPlaceConstructionIlist) {
EXPECT_EQ(expected_values, v.values);
}
+TEST(AnyTest, InPlaceConstructionIlistVariableTemplate) {
+ const CopyOnly copy_only{};
+ absl::any o(absl::in_place_type<ListMoveOnlyCopyOnly>, {1, 2, 3, 4},
+ MoveOnly(), copy_only);
+ auto& v = absl::any_cast<ListMoveOnlyCopyOnly&>(o);
+ std::vector<int> expected_values = {1, 2, 3, 4};
+ EXPECT_EQ(expected_values, v.values);
+}
+
TEST(AnyTest, InPlaceConstructionIlistWithCV) {
const CopyOnly copy_only{};
absl::any o(absl::in_place_type_t<const volatile ListMoveOnlyCopyOnly>(),
@@ -193,11 +231,25 @@ TEST(AnyTest, InPlaceConstructionIlistWithCV) {
EXPECT_EQ(expected_values, v.values);
}
+TEST(AnyTest, InPlaceConstructionIlistWithCVVariableTemplate) {
+ const CopyOnly copy_only{};
+ absl::any o(absl::in_place_type<const volatile ListMoveOnlyCopyOnly>,
+ {1, 2, 3, 4}, MoveOnly(), copy_only);
+ auto& v = absl::any_cast<ListMoveOnlyCopyOnly&>(o);
+ std::vector<int> expected_values = {1, 2, 3, 4};
+ EXPECT_EQ(expected_values, v.values);
+}
+
TEST(AnyTest, InPlaceNoArgs) {
absl::any o(absl::in_place_type_t<int>{});
EXPECT_EQ(0, absl::any_cast<int&>(o));
}
+TEST(AnyTest, InPlaceNoArgsVariableTemplate) {
+ absl::any o(absl::in_place_type<int>);
+ EXPECT_EQ(0, absl::any_cast<int&>(o));
+}
+
template <typename Enabler, typename T, typename... Args>
struct CanEmplaceAnyImpl : std::false_type {};
@@ -501,7 +553,7 @@ TEST(AnyTest, Copy) {
InstanceTracker tracker_raii;
{
- absl::any o(absl::in_place_type_t<CopyableOnlyInstance>{}, 123);
+ absl::any o(absl::in_place_type<CopyableOnlyInstance>, 123);
CopyableOnlyInstance* f1 = absl::any_cast<CopyableOnlyInstance>(&o);
absl::any o2(o);
@@ -622,7 +674,7 @@ TEST(AnyTest, ThrowBadAlloc) {
}
{
- absl::any a(absl::in_place_type_t<int>{});
+ absl::any a(absl::in_place_type<int>);
ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<float&>(a));
ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const float&>(a));
ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<float&&>(absl::any{}));
@@ -665,7 +717,7 @@ TEST(AnyTest, FailedCopy) {
}
{
- absl::any src(absl::in_place_type_t<BadCopyable>{});
+ absl::any src(absl::in_place_type<BadCopyable>);
ABSL_ANY_TEST_EXPECT_BAD_COPY(absl::any{src});
}
@@ -677,21 +729,21 @@ TEST(AnyTest, FailedCopy) {
{
BadCopyable bad;
- absl::any target(absl::in_place_type_t<BadCopyable>{});
+ absl::any target(absl::in_place_type<BadCopyable>);
ABSL_ANY_TEST_EXPECT_BAD_COPY(target = bad);
EXPECT_TRUE(target.has_value());
}
{
- absl::any src(absl::in_place_type_t<BadCopyable>{});
+ absl::any src(absl::in_place_type<BadCopyable>);
absl::any target;
ABSL_ANY_TEST_EXPECT_BAD_COPY(target = src);
EXPECT_FALSE(target.has_value());
}
{
- absl::any src(absl::in_place_type_t<BadCopyable>{});
- absl::any target(absl::in_place_type_t<BadCopyable>{});
+ absl::any src(absl::in_place_type<BadCopyable>);
+ absl::any target(absl::in_place_type<BadCopyable>);
ABSL_ANY_TEST_EXPECT_BAD_COPY(target = src);
EXPECT_TRUE(target.has_value());
}
@@ -707,7 +759,7 @@ TEST(AnyTest, FailedEmplace) {
{
BadCopyable bad;
- absl::any target(absl::in_place_type_t<int>{});
+ absl::any target(absl::in_place_type<int>);
ABSL_ANY_TEST_EXPECT_BAD_COPY(target.emplace<BadCopyable>(bad));
#if defined(ABSL_HAVE_STD_ANY) && defined(__GLIBCXX__)
// libstdc++ std::any::emplace() implementation (as of 7.2) has a bug: if an
diff --git a/absl/types/variant_test.cc b/absl/types/variant_test.cc
index ab40ed2a..b9c98118 100644
--- a/absl/types/variant_test.cc
+++ b/absl/types/variant_test.cc
@@ -384,7 +384,7 @@ struct MoveOnly {
TEST(VariantTest, TestMoveConstruct) {
using V = variant<MoveOnly<class A>, MoveOnly<class B>, MoveOnly<class C>>;
- V v(in_place_index_t<1>{}, 10);
+ V v(in_place_index<1>, 10);
V v2 = absl::move(v);
EXPECT_EQ(10, absl::get<1>(v2).value);
}
@@ -483,6 +483,29 @@ TEST(VariantTest, InPlaceType) {
EXPECT_THAT(absl::get<std::vector<int>>(v5), ::testing::ElementsAre(1, 2, 3));
}
+TEST(VariantTest, InPlaceTypeVariableTemplate) {
+ using Var = variant<int, std::string, NonCopyable, std::vector<int>>;
+
+ Var v1(in_place_type<int>, 7);
+ ASSERT_TRUE(absl::holds_alternative<int>(v1));
+ EXPECT_EQ(7, absl::get<int>(v1));
+
+ Var v2(in_place_type<std::string>, "ABC");
+ ASSERT_TRUE(absl::holds_alternative<std::string>(v2));
+ EXPECT_EQ("ABC", absl::get<std::string>(v2));
+
+ Var v3(in_place_type<std::string>, "ABC", 2);
+ ASSERT_TRUE(absl::holds_alternative<std::string>(v3));
+ EXPECT_EQ("AB", absl::get<std::string>(v3));
+
+ Var v4(in_place_type<NonCopyable>);
+ ASSERT_TRUE(absl::holds_alternative<NonCopyable>(v4));
+
+ Var v5(in_place_type<std::vector<int>>, {1, 2, 3});
+ ASSERT_TRUE(absl::holds_alternative<std::vector<int>>(v5));
+ EXPECT_THAT(absl::get<std::vector<int>>(v5), ::testing::ElementsAre(1, 2, 3));
+}
+
TEST(VariantTest, InPlaceTypeInitializerList) {
using Var =
variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>;
@@ -492,6 +515,15 @@ TEST(VariantTest, InPlaceTypeInitializerList) {
EXPECT_EQ(6, absl::get<MoveOnlyWithListConstructor>(v1).value);
}
+TEST(VariantTest, InPlaceTypeInitializerListVariabletemplate) {
+ using Var =
+ variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>;
+
+ Var v1(in_place_type<MoveOnlyWithListConstructor>, {1, 2, 3, 4, 5}, 6);
+ ASSERT_TRUE(absl::holds_alternative<MoveOnlyWithListConstructor>(v1));
+ EXPECT_EQ(6, absl::get<MoveOnlyWithListConstructor>(v1).value);
+}
+
TEST(VariantTest, InPlaceIndex) {
using Var = variant<int, std::string, NonCopyable, std::vector<int>>;
@@ -519,6 +551,33 @@ TEST(VariantTest, InPlaceIndex) {
EXPECT_THAT(absl::get<std::vector<int>>(v5), ::testing::ElementsAre(1, 2, 3));
}
+TEST(VariantTest, InPlaceIndexVariableTemplate) {
+ using Var = variant<int, std::string, NonCopyable, std::vector<int>>;
+
+ Var v1(in_place_index<0>, 7);
+ ASSERT_TRUE(absl::holds_alternative<int>(v1));
+ EXPECT_EQ(7, absl::get<int>(v1));
+
+ Var v2(in_place_index<1>, "ABC");
+ ASSERT_TRUE(absl::holds_alternative<std::string>(v2));
+ EXPECT_EQ("ABC", absl::get<std::string>(v2));
+
+ Var v3(in_place_index<1>, "ABC", 2);
+ ASSERT_TRUE(absl::holds_alternative<std::string>(v3));
+ EXPECT_EQ("AB", absl::get<std::string>(v3));
+
+ Var v4(in_place_index<2>);
+ EXPECT_TRUE(absl::holds_alternative<NonCopyable>(v4));
+
+ // Verify that a variant with only non-copyables can still be constructed.
+ EXPECT_TRUE(absl::holds_alternative<NonCopyable>(
+ variant<NonCopyable>(in_place_index<0>)));
+
+ Var v5(in_place_index<3>, {1, 2, 3});
+ ASSERT_TRUE(absl::holds_alternative<std::vector<int>>(v5));
+ EXPECT_THAT(absl::get<std::vector<int>>(v5), ::testing::ElementsAre(1, 2, 3));
+}
+
TEST(VariantTest, InPlaceIndexInitializerList) {
using Var =
variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>;
@@ -528,6 +587,15 @@ TEST(VariantTest, InPlaceIndexInitializerList) {
EXPECT_EQ(6, absl::get<MoveOnlyWithListConstructor>(v1).value);
}
+TEST(VariantTest, InPlaceIndexInitializerListVariableTemplate) {
+ using Var =
+ variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>;
+
+ Var v1(in_place_index<3>, {1, 2, 3, 4, 5}, 6);
+ ASSERT_TRUE(absl::holds_alternative<MoveOnlyWithListConstructor>(v1));
+ EXPECT_EQ(6, absl::get<MoveOnlyWithListConstructor>(v1).value);
+}
+
////////////////////
// [variant.dtor] //
////////////////////
@@ -576,7 +644,7 @@ TEST(VariantTest, TestDtorValuelessByException)
{
using Variant = VariantFactory<IncrementInDtor>::Type;
- Variant v(in_place_index_t<0>(), counter_adjuster);
+ Variant v(in_place_index<0>, counter_adjuster);
EXPECT_EQ(0, counter);
ToValuelessByException(v);
@@ -810,7 +878,7 @@ TEST(VariantTest, TestBackupAssign) {
TEST(VariantTest, TestEmplaceBasic) {
using Variant = variant<int, char>;
- Variant v(absl::in_place_index_t<0>{}, 0);
+ Variant v(absl::in_place_index<0>, 0);
{
char& emplace_result = v.emplace<char>();
@@ -837,7 +905,7 @@ TEST(VariantTest, TestEmplaceInitializerList) {
using Var =
variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>;
- Var v1(absl::in_place_index_t<0>{}, 555);
+ Var v1(absl::in_place_index<0>, 555);
MoveOnlyWithListConstructor& emplace_result =
v1.emplace<MoveOnlyWithListConstructor>({1, 2, 3, 4, 5}, 6);
ASSERT_TRUE(absl::holds_alternative<MoveOnlyWithListConstructor>(v1));
@@ -848,7 +916,7 @@ TEST(VariantTest, TestEmplaceInitializerList) {
TEST(VariantTest, TestEmplaceIndex) {
using Variant = variant<int, char>;
- Variant v(absl::in_place_index_t<0>{}, 555);
+ Variant v(absl::in_place_index<0>, 555);
{
char& emplace_result = v.emplace<1>();
@@ -875,7 +943,7 @@ TEST(VariantTest, TestEmplaceIndexInitializerList) {
using Var =
variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>;
- Var v1(absl::in_place_index_t<0>{}, 555);
+ Var v1(absl::in_place_index<0>, 555);
MoveOnlyWithListConstructor& emplace_result =
v1.emplace<3>({1, 2, 3, 4, 5}, 6);
ASSERT_TRUE(absl::holds_alternative<MoveOnlyWithListConstructor>(v1));
@@ -924,7 +992,7 @@ TEST(VariantTest, NotValuelessByException) {
TEST(VariantTest, IndexValuelessByException) {
using Var = variant<MoveCanThrow, std::string, double>;
- Var v(absl::in_place_index_t<0>{});
+ Var v(absl::in_place_index<0>);
EXPECT_EQ(0, v.index());
ToValuelessByException(v);
EXPECT_EQ(absl::variant_npos, v.index());
@@ -935,7 +1003,7 @@ TEST(VariantTest, IndexValuelessByException) {
TEST(VariantTest, ValuelessByException) {
using Var = variant<MoveCanThrow, std::string, double>;
- Var v(absl::in_place_index_t<0>{});
+ Var v(absl::in_place_index<0>);
EXPECT_FALSE(v.valueless_by_exception());
ToValuelessByException(v);
EXPECT_TRUE(v.valueless_by_exception());
@@ -966,7 +1034,7 @@ TEST(VariantTest, MemberSwap) {
using V = variant<MoveCanThrow, std::string, int>;
int i = 33;
std::string s = "abc";
- V valueless(in_place_index_t<0>{});
+ V valueless(in_place_index<0>);
ToValuelessByException(valueless);
{
// lhs and rhs holds different alternative
@@ -1127,7 +1195,7 @@ TEST(VariantTest, GetIndex) {
using Var = variant<int, std::string, double, int>;
{
- Var v(absl::in_place_index_t<0>{}, 0);
+ Var v(absl::in_place_index<0>, 0);
using LValueGetType = decltype(absl::get<0>(v));
using RValueGetType = decltype(absl::get<0>(absl::move(v)));
@@ -1187,7 +1255,7 @@ TEST(VariantTest, GetIndex) {
}
{
- Var v(absl::in_place_index_t<0>{}, 0);
+ Var v(absl::in_place_index<0>, 0);
v.emplace<3>(1);
using LValueGetType = decltype(absl::get<3>(v));
@@ -1334,7 +1402,7 @@ TEST(VariantTest, GetIfIndex) {
using Var = variant<int, std::string, double, int>;
{
- Var v(absl::in_place_index_t<0>{}, 0);
+ Var v(absl::in_place_index<0>, 0);
EXPECT_TRUE(noexcept(absl::get_if<0>(&v)));
{
@@ -1492,7 +1560,7 @@ TEST(VariantTest, GetIfIndex) {
}
{
- Var v(absl::in_place_index_t<0>{}, 0);
+ Var v(absl::in_place_index<0>, 0);
v.emplace<3>(1);
EXPECT_TRUE(noexcept(absl::get_if<3>(&v)));
@@ -1638,8 +1706,8 @@ TEST(VariantTest, OperatorRelational) {
TEST(VariantTest, ValuelessOperatorEquals) {
variant<MoveCanThrow, std::string> int_v(1), string_v("Hello"),
- valueless(absl::in_place_index_t<0>{}),
- other_valueless(absl::in_place_index_t<0>{});
+ valueless(absl::in_place_index<0>),
+ other_valueless(absl::in_place_index<0>);
ToValuelessByException(valueless);
ToValuelessByException(other_valueless);
@@ -1660,8 +1728,8 @@ TEST(VariantTest, ValuelessOperatorEquals) {
TEST(VariantTest, ValuelessOperatorRelational) {
variant<MoveCanThrow, std::string> int_v(1), string_v("Hello"),
- valueless(absl::in_place_index_t<0>{}),
- other_valueless(absl::in_place_index_t<0>{});
+ valueless(absl::in_place_index<0>),
+ other_valueless(absl::in_place_index<0>);
ToValuelessByException(valueless);
ToValuelessByException(other_valueless);
@@ -2008,8 +2076,8 @@ TEST(VariantTest, Hash) {
#if !(defined(_MSC_VER) && defined(ABSL_HAVE_STD_VARIANT))
{
// same value as different alternative
- variant<int, int> v0(in_place_index_t<0>{}, 42);
- variant<int, int> v1(in_place_index_t<1>{}, 42);
+ variant<int, int> v0(in_place_index<0>, 42);
+ variant<int, int> v1(in_place_index<1>, 42);
std::hash<variant<int, int>> hash;
EXPECT_NE(hash(v0), hash(v1));
}
@@ -2605,7 +2673,7 @@ TEST(VariantTest, MoveCtorBug) {
};
{
using V = absl::variant<TrivialCopyNontrivialMove, int>;
- V v1(absl::in_place_index_t<0>{});
+ V v1(absl::in_place_index<0>);
// this should invoke the move ctor, rather than the trivial copy ctor.
V v2(std::move(v1));
EXPECT_TRUE(absl::get<0>(v2).called);
@@ -2613,7 +2681,7 @@ TEST(VariantTest, MoveCtorBug) {
{
// this case failed to compile before our fix due to a GCC bug.
using V = absl::variant<int, TrivialCopyNontrivialMove>;
- V v1(absl::in_place_index_t<1>{});
+ V v1(absl::in_place_index<1>);
// this should invoke the move ctor, rather than the trivial copy ctor.
V v2(std::move(v1));
EXPECT_TRUE(absl::get<1>(v2).called);
diff --git a/absl/utility/utility.h b/absl/utility/utility.h
index 853c1fb8..7686db12 100644
--- a/absl/utility/utility.h
+++ b/absl/utility/utility.h
@@ -113,6 +113,20 @@ struct Gen<T, 0> {
using type = integer_sequence<T>;
};
+template <typename T>
+struct InPlaceTypeTag {
+ explicit InPlaceTypeTag() = delete;
+ InPlaceTypeTag(const InPlaceTypeTag&) = delete;
+ InPlaceTypeTag& operator=(const InPlaceTypeTag&) = delete;
+};
+
+template <size_t I>
+struct InPlaceIndexTag {
+ explicit InPlaceIndexTag() = delete;
+ InPlaceIndexTag(const InPlaceIndexTag&) = delete;
+ InPlaceIndexTag& operator=(const InPlaceIndexTag&) = delete;
+};
+
} // namespace utility_internal
// Compile-time sequences of integers
@@ -162,6 +176,7 @@ ABSL_INTERNAL_INLINE_CONSTEXPR(in_place_t, in_place, {});
#endif // ABSL_HAVE_STD_OPTIONAL
#if defined(ABSL_HAVE_STD_ANY) || defined(ABSL_HAVE_STD_VARIANT)
+using std::in_place_type;
using std::in_place_type_t;
#else
@@ -171,10 +186,14 @@ using std::in_place_type_t;
// be specified, such as with `absl::any`, designed to be a drop-in replacement
// for C++17's `std::in_place_type_t`.
template <typename T>
-struct in_place_type_t {};
+using in_place_type_t = void (*)(utility_internal::InPlaceTypeTag<T>);
+
+template <typename T>
+void in_place_type(utility_internal::InPlaceTypeTag<T>) {}
#endif // ABSL_HAVE_STD_ANY || ABSL_HAVE_STD_VARIANT
#ifdef ABSL_HAVE_STD_VARIANT
+using std::in_place_index;
using std::in_place_index_t;
#else
@@ -184,7 +203,10 @@ using std::in_place_index_t;
// be specified, such as with `absl::any`, designed to be a drop-in replacement
// for C++17's `std::in_place_index_t`.
template <size_t I>
-struct in_place_index_t {};
+using in_place_index_t = void (*)(utility_internal::InPlaceIndexTag<I>);
+
+template <size_t I>
+void in_place_index(utility_internal::InPlaceIndexTag<I>) {}
#endif // ABSL_HAVE_STD_VARIANT
// Constexpr move and forward