diff --git a/CMake/AbseilHelpers.cmake b/CMake/AbseilHelpers.cmake index 67b97fe14..28fefaa67 100644 --- a/CMake/AbseilHelpers.cmake +++ b/CMake/AbseilHelpers.cmake @@ -104,7 +104,10 @@ function(absl_cc_library) endif() if(NOT ABSL_CC_LIB_IS_INTERFACE) - add_library(${_NAME} STATIC "") + # CMake creates static libraries by default. Users can specify + # -DBUILD_SHARED_LIBS=ON during initial configuration to build shared + # libraries instead. + add_library(${_NAME} "") target_sources(${_NAME} PRIVATE ${ABSL_CC_LIB_SRCS} ${ABSL_CC_LIB_HDRS}) target_include_directories(${_NAME} PUBLIC diff --git a/WORKSPACE b/WORKSPACE index 572f5b1f7..f2b104644 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -36,10 +36,10 @@ http_archive( # C++ rules for Bazel. http_archive( name = "rules_cc", - sha256 = "67412176974bfce3f4cf8bdaff39784a72ed709fc58def599d1f68710b58d68b", - strip_prefix = "rules_cc-b7fe9697c0c76ab2fd431a891dbb9a6a32ed7c3e", + sha256 = "9a446e9dd9c1bb180c86977a8dc1e9e659550ae732ae58bd2e8fd51e15b2c91d", + strip_prefix = "rules_cc-262ebec3c2296296526740db4aefce68c80de7fa", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/rules_cc/archive/b7fe9697c0c76ab2fd431a891dbb9a6a32ed7c3e.zip", - "https://github.com/bazelbuild/rules_cc/archive/b7fe9697c0c76ab2fd431a891dbb9a6a32ed7c3e.zip", + "https://mirror.bazel.build/github.com/bazelbuild/rules_cc/archive/262ebec3c2296296526740db4aefce68c80de7fa.zip", + "https://github.com/bazelbuild/rules_cc/archive/262ebec3c2296296526740db4aefce68c80de7fa.zip", ], ) diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index ffeca6307..6fc712d96 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -87,6 +87,7 @@ cc_library( name = "config", hdrs = [ "config.h", + "options.h", "policy_checks.h", ], copts = ABSL_DEFAULT_COPTS, @@ -137,7 +138,7 @@ cc_library( "//conditions:default": ["-pthread"], }) + ABSL_DEFAULT_LINKOPTS, visibility = [ - "//absl:__subpackages__", + "//visibility:public", ], deps = [ ":base", diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index 2698213c5..9550cdb2d 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt @@ -75,6 +75,7 @@ absl_cc_library( config HDRS "config.h" + "options.h" "policy_checks.h" COPTS ${ABSL_DEFAULT_COPTS} diff --git a/absl/base/config.h b/absl/base/config.h index 24851fa33..46a84f1a7 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -63,6 +63,7 @@ #include #endif +#include "absl/base/options.h" #include "absl/base/policy_checks.h" // ----------------------------------------------------------------------------- @@ -468,6 +469,68 @@ #define ABSL_HAVE_STD_STRING_VIEW 1 #endif +// ABSL_USES_STD_ANY +// +// Indicates whether absl::any is an alias for std::any. +#if !defined(ABSL_OPTION_USE_STD_ANY) +#error options.h is misconfigured. +#elif ABSL_OPTION_USE_STD_ANY == 0 || \ + (ABSL_OPTION_USE_STD_ANY == 2 && !defined(ABSL_HAVE_STD_ANY)) +#undef ABSL_USES_STD_ANY +#elif ABSL_OPTION_USE_STD_ANY == 1 || \ + (ABSL_OPTION_USE_STD_ANY == 2 && defined(ABSL_HAVE_STD_ANY)) +#define ABSL_USES_STD_ANY 1 +#else +#error options.h is misconfigured. +#endif + +// ABSL_USES_STD_OPTIONAL +// +// Indicates whether absl::optional is an alias for std::optional. +#if !defined(ABSL_OPTION_USE_STD_OPTIONAL) +#error options.h is misconfigured. +#elif ABSL_OPTION_USE_STD_OPTIONAL == 0 || \ + (ABSL_OPTION_USE_STD_OPTIONAL == 2 && !defined(ABSL_HAVE_STD_OPTIONAL)) +#undef ABSL_USES_STD_OPTIONAL +#elif ABSL_OPTION_USE_STD_OPTIONAL == 1 || \ + (ABSL_OPTION_USE_STD_OPTIONAL == 2 && defined(ABSL_HAVE_STD_OPTIONAL)) +#define ABSL_USES_STD_OPTIONAL 1 +#else +#error options.h is misconfigured. +#endif + +// ABSL_USES_STD_VARIANT +// +// Indicates whether absl::variant is an alias for std::variant. +#if !defined(ABSL_OPTION_USE_STD_VARIANT) +#error options.h is misconfigured. +#elif ABSL_OPTION_USE_STD_VARIANT == 0 || \ + (ABSL_OPTION_USE_STD_VARIANT == 2 && !defined(ABSL_HAVE_STD_VARIANT)) +#undef ABSL_USES_STD_VARIANT +#elif ABSL_OPTION_USE_STD_VARIANT == 1 || \ + (ABSL_OPTION_USE_STD_VARIANT == 2 && defined(ABSL_HAVE_STD_VARIANT)) +#define ABSL_USES_STD_VARIANT 1 +#else +#error options.h is misconfigured. +#endif + +// ABSL_USES_STD_STRING_VIEW +// +// Indicates whether absl::string_view is an alias for std::string_view. +#if !defined(ABSL_OPTION_USE_STD_STRING_VIEW) +#error options.h is misconfigured. +#elif ABSL_OPTION_USE_STD_STRING_VIEW == 0 || \ + (ABSL_OPTION_USE_STD_STRING_VIEW == 2 && \ + !defined(ABSL_HAVE_STD_STRING_VIEW)) +#undef ABSL_USES_STD_STRING_VIEW +#elif ABSL_OPTION_USE_STD_STRING_VIEW == 1 || \ + (ABSL_OPTION_USE_STD_STRING_VIEW == 2 && \ + defined(ABSL_HAVE_STD_STRING_VIEW)) +#define ABSL_USES_STD_STRING_VIEW 1 +#else +#error options.h is misconfigured. +#endif + // In debug mode, MSVC 2017's std::variant throws a EXCEPTION_ACCESS_VIOLATION // SEH exception from emplace for variant when constructing the // struct can throw. This defeats some of variant_test and diff --git a/absl/base/internal/endian.h b/absl/base/internal/endian.h index b43c9a46e..8233cb524 100644 --- a/absl/base/internal/endian.h +++ b/absl/base/internal/endian.h @@ -19,9 +19,6 @@ // The following guarantees declaration of the byte swap functions #ifdef _MSC_VER #include // NOLINT(build/include) -#elif defined(__APPLE__) -// macOS / Darwin features -#include #elif defined(__FreeBSD__) #include #elif defined(__GLIBC__) @@ -63,11 +60,6 @@ inline uint16_t gbswap_16(uint16_t host_int) { return _byteswap_ushort(host_int); } -#elif defined(__APPLE__) -inline uint64_t gbswap_64(uint64_t host_int) { return OSSwapInt16(host_int); } -inline uint32_t gbswap_32(uint32_t host_int) { return OSSwapInt32(host_int); } -inline uint16_t gbswap_16(uint16_t host_int) { return OSSwapInt64(host_int); } - #else inline uint64_t gbswap_64(uint64_t host_int) { #if defined(__GNUC__) && defined(__x86_64__) && !defined(__APPLE__) diff --git a/absl/base/options.h b/absl/base/options.h new file mode 100644 index 000000000..3961e63f4 --- /dev/null +++ b/absl/base/options.h @@ -0,0 +1,188 @@ +#ifndef ABSL_BASE_OPTIONS_H_ +#define ABSL_BASE_OPTIONS_H_ + +// 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. +// +// ----------------------------------------------------------------------------- +// File: options.h +// ----------------------------------------------------------------------------- +// +// This file contains Abseil configuration options for setting specific +// implementations instead of letting Abseil determine which implementation to +// use at compile-time. Setting these options may be useful for package or build +// managers who wish to guarantee ABI stability within binary builds (which are +// otherwise difficult to enforce). +// +// *** IMPORTANT NOTICE FOR PACKAGE MANAGERS: It is important that +// maintainers of package managers who wish to package Abseil read and +// understand this file! *** +// +// Abseil contains a number of possible configuration endpoints, based on +// parameters such as the detected platform, language version, or command-line +// flags used to invoke the underlying binary. As is the case with all +// libraries, binaries which contain Abseil code must ensure that separate +// packages use the same compiled copy of Abseil to avoid a diamond dependency +// problem, which can occur if two packages built with different Abseil +// configuration settings are linked together. Diamond dependency problems in +// C++ may manifest as violations to the One Definition Rule (ODR) (resulting in +// linker errors), or undefined behavior (resulting in crashes). +// +// Diamond dependency problems can be avoided if all packages utilize the same +// exact version of Abseil. Building from source code with the same compilation +// parameters is the easiest way to avoid such dependency problems. However, for +// package managers who cannot control such compilation parameters, we are +// providing the file to allow you to inject ABI (Application Binary Interface) +// stability across builds. Settings options in this file will neither change +// API nor ABI, providing a stable copy of Abseil between packages. +// +// Care must be taken to keep options within these configurations isolated +// from any other dynamic settings, such as command-line flags which could alter +// these options. This file is provided specifically to help build and package +// managers provide a stable copy of Abseil within their libraries and binaries; +// other developers should not have need to alter the contents of this file. +// +// ----------------------------------------------------------------------------- +// Usage +// ----------------------------------------------------------------------------- +// +// For any particular package release, set the appropriate definitions within +// this file to whatever value makes the most sense for your package(s). Note +// that, by default, most of these options, at the moment, affect the +// implementation of types; future options may affect other implementation +// details. +// +// NOTE: the defaults within this file all assume that Abseil can select the +// proper Abseil implementation at compile-time, which will not be sufficient +// to guarantee ABI stability to package managers. +// +// ----------------------------------------------------------------------------- +// Type Compatibility Options +// ----------------------------------------------------------------------------- +// +// ABSL_OPTION_USE_STD_ANY +// +// This option controls whether absl::any is implemented as an alias to +// std::any, or as an independent implementation. +// +// A value of 0 means to use Abseil's implementation. This requires only C++11 +// support, and is expected to work on every toolchain we support. +// +// A value of 1 means to use an alias to std::any. This requires that all code +// using Abseil is built in C++17 mode or later. +// +// A value of 2 means to detect the C++ version being used to compile Abseil, +// and use an alias only if a working std::any is available. This option is +// useful when you are building your entire program, including all of its +// dependencies, from source. It should not be used otherwise -- for example, +// if you are distributing Abseil in a binary package manager -- since in +// mode 2, absl::any will name a different type, with a different mangled name +// and binary layout, depending on the compiler flags passed by the end user. +// For more info, see https://abseil.io/about/design/dropin-types. +// +// User code should not inspect this macro. To check in the preprocessor if +// absl::any is a typedef of std::any, use the feature macro ABSL_USES_STD_ANY. + +#define ABSL_OPTION_USE_STD_ANY 2 + + +// ABSL_OPTION_USE_STD_OPTIONAL +// +// This option controls whether absl::optional is implemented as an alias to +// std::optional, or as an independent implementation. +// +// A value of 0 means to use Abseil's implementation. This requires only C++11 +// support, and is expected to work on every toolchain we support. +// +// A value of 1 means to use an alias to std::optional. This requires that all +// code using Abseil is built in C++17 mode or later. +// +// A value of 2 means to detect the C++ version being used to compile Abseil, +// and use an alias only if a working std::optional is available. This option +// is useful when you are building your program from source. It should not be +// used otherwise -- for example, if you are distributing Abseil in a binary +// package manager -- since in mode 2, absl::optional will name a different +// type, with a different mangled name and binary layout, depending on the +// compiler flags passed by the end user. For more info, see +// https://abseil.io/about/design/dropin-types. + +// A value of 2 means to detect the C++ version being used to compile Abseil, +// and use an alias only if a working std::optional is available. This option +// should not be used when your program is not built from source -- for example, +// if you are distributing Abseil in a binary package manager -- since in mode +// 2, absl::optional will name a different template class, with a different +// mangled name and binary layout, depending on the compiler flags passed by the +// end user. +// +// User code should not inspect this macro. To check in the preprocessor if +// absl::optional is a typedef of std::optional, use the feature macro +// ABSL_USES_STD_OPTIONAL. + +#define ABSL_OPTION_USE_STD_OPTIONAL 2 + + +// ABSL_OPTION_USE_STD_STRING_VIEW +// +// This option controls whether absl::string_view is implemented as an alias to +// std::string_view, or as an independent implementation. +// +// A value of 0 means to use Abseil's implementation. This requires only C++11 +// support, and is expected to work on every toolchain we support. +// +// A value of 1 means to use an alias to std::string_view. This requires that +// all code using Abseil is built in C++17 mode or later. +// +// A value of 2 means to detect the C++ version being used to compile Abseil, +// and use an alias only if a working std::string_view is available. This +// option is useful when you are building your program from source. It should +// not be used otherwise -- for example, if you are distributing Abseil in a +// binary package manager -- since in mode 2, absl::string_view will name a +// different type, with a different mangled name and binary layout, depending on +// the compiler flags passed by the end user. For more info, see +// https://abseil.io/about/design/dropin-types. +// +// User code should not inspect this macro. To check in the preprocessor if +// absl::string_view is a typedef of std::string_view, use the feature macro +// ABSL_USES_STD_STRING_VIEW. + +#define ABSL_OPTION_USE_STD_STRING_VIEW 2 + + +// ABSL_OPTION_USE_STD_VARIANT +// +// This option controls whether absl::variant is implemented as an alias to +// std::variant, or as an independent implementation. +// +// A value of 0 means to use Abseil's implementation. This requires only C++11 +// support, and is expected to work on every toolchain we support. +// +// A value of 1 means to use an alias to std::variant. This requires that all +// code using Abseil is built in C++17 mode or later. +// +// A value of 2 means to detect the C++ version being used to compile Abseil, +// and use an alias only if a working std::variant is available. This option +// is useful when you are building your program from source. It should not be +// used otherwise -- for example, if you are distributing Abseil in a binary +// package manager -- since in mode 2, absl::variant will name a different +// type, with a different mangled name and binary layout, depending on the +// compiler flags passed by the end user. For more info, see +// https://abseil.io/about/design/dropin-types. +// +// User code should not inspect this macro. To check in the preprocessor if +// absl::variant is a typedef of std::variant, use the feature macro +// ABSL_USES_STD_VARIANT. + +#define ABSL_OPTION_USE_STD_VARIANT 2 + +#endif // ABSL_BASE_OPTIONS_H_ diff --git a/absl/container/flat_hash_map_test.cc b/absl/container/flat_hash_map_test.cc index 6cff1a257..02d1f879d 100644 --- a/absl/container/flat_hash_map_test.cc +++ b/absl/container/flat_hash_map_test.cc @@ -214,7 +214,7 @@ TEST(FlatHashMap, MergeExtractInsert) { EXPECT_THAT(m, UnorderedElementsAre(Pair(1, 17), Pair(2, 9))); } -#if (defined(ABSL_HAVE_STD_ANY) || !defined(_LIBCPP_VERSION)) && \ +#if (defined(ABSL_USES_STD_ANY) || !defined(_LIBCPP_VERSION)) && \ !defined(__EMSCRIPTEN__) TEST(FlatHashMap, Any) { absl::flat_hash_map m; @@ -246,7 +246,7 @@ TEST(FlatHashMap, Any) { ASSERT_NE(it2, m2.end()); EXPECT_EQ(7, it2->second); } -#endif // (defined(ABSL_HAVE_STD_ANY) || !defined(_LIBCPP_VERSION)) && +#endif // (defined(ABSL_USES_STD_ANY) || !defined(_LIBCPP_VERSION)) && // !defined(__EMSCRIPTEN__) } // namespace diff --git a/absl/container/internal/inlined_vector.h b/absl/container/internal/inlined_vector.h index 7d08f7e30..f678c88da 100644 --- a/absl/container/internal/inlined_vector.h +++ b/absl/container/internal/inlined_vector.h @@ -471,12 +471,9 @@ auto Storage::Initialize(ValueAdapter values, size_type new_size) // safe to take on the allocation with size `0`. If `ConstructElements(...)` // throws, deallocation will be automatically handled by `~Storage()`. size_type new_capacity = ComputeCapacity(GetInlinedCapacity(), new_size); - pointer new_data = AllocatorTraits::allocate(*GetAllocPtr(), new_capacity); - - SetAllocatedData(new_data, new_capacity); + construct_data = AllocatorTraits::allocate(*GetAllocPtr(), new_capacity); + SetAllocatedData(construct_data, new_capacity); SetIsAllocated(); - - construct_data = new_data; } else { construct_data = GetInlinedData(); } @@ -503,9 +500,7 @@ auto Storage::Assign(ValueAdapter values, size_type new_size) -> void { if (new_size > storage_view.capacity) { size_type new_capacity = ComputeCapacity(storage_view.capacity, new_size); - pointer new_data = allocation_tx.Allocate(new_capacity); - - construct_loop = {new_data, new_size}; + construct_loop = {allocation_tx.Allocate(new_capacity), new_size}; destroy_loop = {storage_view.data, storage_view.size}; } else if (new_size > storage_view.size) { assign_loop = {storage_view.data, storage_view.size}; @@ -552,7 +547,6 @@ auto Storage::Resize(ValueAdapter values, size_type new_size) -> void { if (new_size > storage_view.capacity) { size_type new_capacity = ComputeCapacity(storage_view.capacity, new_size); pointer new_data = allocation_tx.Allocate(new_capacity); - construct_loop = {new_data + storage_view.size, new_size - storage_view.size}; move_construct_loop = {new_data, storage_view.size}; @@ -690,14 +684,14 @@ auto Storage::EmplaceBack(Args&&... args) -> reference { pointer construct_data; if (storage_view.size == storage_view.capacity) { size_type new_capacity = NextCapacity(storage_view.capacity); - pointer new_data = allocation_tx.Allocate(new_capacity); - - construct_data = new_data; + construct_data = allocation_tx.Allocate(new_capacity); } else { construct_data = storage_view.data; } - AllocatorTraits::construct(*GetAllocPtr(), construct_data + storage_view.size, + pointer last_ptr = construct_data + storage_view.size; + + AllocatorTraits::construct(*GetAllocPtr(), last_ptr, std::forward(args)...); if (allocation_tx.DidAllocate()) { @@ -707,8 +701,7 @@ auto Storage::EmplaceBack(Args&&... args) -> reference { storage_view.size); } ABSL_INTERNAL_CATCH_ANY { - AllocatorTraits::destroy(*GetAllocPtr(), - construct_data + storage_view.size); + AllocatorTraits::destroy(*GetAllocPtr(), last_ptr); ABSL_INTERNAL_RETHROW; } @@ -721,7 +714,7 @@ auto Storage::EmplaceBack(Args&&... args) -> reference { } AddSize(1); - return *(construct_data + storage_view.size); + return *last_ptr; } template @@ -793,9 +786,7 @@ auto Storage::ShrinkToFit() -> void { pointer construct_data; if (storage_view.size > GetInlinedCapacity()) { size_type new_capacity = storage_view.size; - pointer new_data = allocation_tx.Allocate(new_capacity); - - construct_data = new_data; + construct_data = allocation_tx.Allocate(new_capacity); } else { construct_data = GetInlinedData(); } diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 9992ba4b8..9079a73e5 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -668,7 +668,7 @@ class raw_hash_set { } ctrl_t* ctrl_ = nullptr; - // To avoid uninitialized member warnigs, put slot_ in an anonymous union. + // To avoid uninitialized member warnings, put slot_ in an anonymous union. // The member is not initialized on singleton and end iterators. union { slot_type* slot_; diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h index 76959cdef..d57a87923 100644 --- a/absl/meta/type_traits.h +++ b/absl/meta/type_traits.h @@ -145,6 +145,18 @@ using IsMoveAssignableImpl = decltype(std::declval() = std::declval()); } // namespace type_traits_internal +// MSVC 19.20 has a regression that causes our workarounds to fail, but their +// std forms now appear to be compliant. +#if defined(_MSC_VER) && !defined(__clang__) && (_MSC_VER >= 1920) + +template +using is_copy_assignable = std::is_copy_assignable; + +template +using is_move_assignable = std::is_move_assignable; + +#else + template struct is_copy_assignable : type_traits_internal::is_detected< type_traits_internal::IsCopyAssignableImpl, T> { @@ -155,6 +167,8 @@ struct is_move_assignable : type_traits_internal::is_detected< type_traits_internal::IsMoveAssignableImpl, T> { }; +#endif + // void_t() // // Ignores the type of any its arguments and returns `void`. In general, this diff --git a/absl/random/internal/nonsecure_base_test.cc b/absl/random/internal/nonsecure_base_test.cc index d9de99019..698027fc6 100644 --- a/absl/random/internal/nonsecure_base_test.cc +++ b/absl/random/internal/nonsecure_base_test.cc @@ -154,9 +154,10 @@ TEST(NonsecureURBGBase, CompatibleWithDistributionUtils) { TEST(NonsecureURBGBase, CompatibleWithStdDistributions) { ExampleNonsecureURBG rbg; - std::uniform_int_distribution(0, 100)(rbg); - std::uniform_real_distribution()(rbg); - std::bernoulli_distribution(0.2)(rbg); + // Cast to void to suppress [[nodiscard]] warnings + static_cast(std::uniform_int_distribution(0, 100)(rbg)); + static_cast(std::uniform_real_distribution()(rbg)); + static_cast(std::bernoulli_distribution(0.2)(rbg)); } TEST(NonsecureURBGBase, ConsecutiveDefaultInstancesYieldUniqueVariates) { diff --git a/absl/random/log_uniform_int_distribution.h b/absl/random/log_uniform_int_distribution.h index 956a69070..de58bdbe1 100644 --- a/absl/random/log_uniform_int_distribution.h +++ b/absl/random/log_uniform_int_distribution.h @@ -192,13 +192,15 @@ log_uniform_int_distribution::Generate( const double r = std::pow(p.base(), d); const double s = (r * p.base()) - 1.0; - base_e = (r > (std::numeric_limits::max)()) - ? (std::numeric_limits::max)() - : static_cast(r); + base_e = + (r > static_cast((std::numeric_limits::max)())) + ? (std::numeric_limits::max)() + : static_cast(r); - top_e = (s > (std::numeric_limits::max)()) - ? (std::numeric_limits::max)() - : static_cast(s); + top_e = + (s > static_cast((std::numeric_limits::max)())) + ? (std::numeric_limits::max)() + : static_cast(s); } const unsigned_type lo = (base_e >= p.range()) ? p.range() : base_e; diff --git a/absl/strings/numbers.h b/absl/strings/numbers.h index 745de67ad..9b8ec89a8 100644 --- a/absl/strings/numbers.h +++ b/absl/strings/numbers.h @@ -37,7 +37,14 @@ #include #include "absl/base/internal/bits.h" +#ifdef __SSE4_2__ +// TODO(jorg): Remove this when we figure out the right way +// to swap bytes on SSE 4.2 that works with the compilers +// we claim to support. Also, add tests for the compiler +// that doesn't support the Intel _bswap64 intrinsic but +// does support all the SSE 4.2 intrinsics #include "absl/base/internal/endian.h" +#endif #include "absl/base/macros.h" #include "absl/base/port.h" #include "absl/numeric/int128.h" @@ -189,12 +196,12 @@ ABSL_MUST_USE_RESULT bool safe_strtoi_base(absl::string_view s, int_type* out, // Returns the number of non-pad digits of the output (it can never be zero // since 0 has one digit). inline size_t FastHexToBufferZeroPad16(uint64_t val, char* out) { - uint64_t be = absl::big_endian::FromHost64(val); #ifdef __SSE4_2__ + uint64_t be = absl::big_endian::FromHost64(val); const auto kNibbleMask = _mm_set1_epi8(0xf); const auto kHexDigits = _mm_setr_epi8('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'); - auto v = _mm_loadu_si64(reinterpret_cast<__m128i*>(&be)); // load lo dword + auto v = _mm_loadl_epi64(reinterpret_cast<__m128i*>(&be)); // load lo dword auto v4 = _mm_srli_epi64(v, 4); // shift 4 right auto il = _mm_unpacklo_epi8(v4, v); // interleave bytes auto m = _mm_and_si128(il, kNibbleMask); // mask out nibbles @@ -202,7 +209,7 @@ inline size_t FastHexToBufferZeroPad16(uint64_t val, char* out) { _mm_storeu_si128(reinterpret_cast<__m128i*>(out), hexchars); #else for (int i = 0; i < 8; ++i) { - auto byte = (be >> (8 * i)) & 0xFF; + auto byte = (val >> (56 - 8 * i)) & 0xFF; auto* hex = &absl::numbers_internal::kHexTable[byte * 2]; std::memcpy(out + 2 * i, hex, 2); } diff --git a/absl/strings/str_cat.cc b/absl/strings/str_cat.cc index d58778997..4bd56f5f4 100644 --- a/absl/strings/str_cat.cc +++ b/absl/strings/str_cat.cc @@ -27,23 +27,21 @@ namespace absl { AlphaNum::AlphaNum(Hex hex) { + static_assert(numbers_internal::kFastToBufferSize >= 32, + "This function only works when output buffer >= 32 bytes long"); char* const end = &digits_[numbers_internal::kFastToBufferSize]; - char* writer = end; - uint64_t value = hex.value; - do { - *--writer = absl::numbers_internal::kHexChar[value & 0xF]; - value >>= 4; - } while (value != 0); - - char* beg; - if (end - writer < hex.width) { - beg = end - hex.width; - std::fill_n(beg, writer - beg, hex.fill); + auto real_width = + absl::numbers_internal::FastHexToBufferZeroPad16(hex.value, end - 16); + if (real_width >= hex.width) { + piece_ = absl::string_view(end - real_width, real_width); } else { - beg = writer; + // Pad first 16 chars because FastHexToBufferZeroPad16 pads only to 16 and + // max pad width can be up to 20. + std::memset(end - 32, hex.fill, 16); + // Patch up everything else up to the real_width. + std::memset(end - real_width - 16, hex.fill, 16); + piece_ = absl::string_view(end - hex.width, hex.width); } - - piece_ = absl::string_view(beg, end - beg); } AlphaNum::AlphaNum(Dec dec) { diff --git a/absl/strings/str_format.h b/absl/strings/str_format.h index 607e2bcaa..c11c93a24 100644 --- a/absl/strings/str_format.h +++ b/absl/strings/str_format.h @@ -400,6 +400,12 @@ int FPrintF(std::FILE* output, const FormatSpec& format, // This function is functionally equivalent to `std::snprintf()` (and // type-safe); prefer `absl::SNPrintF()` over `std::snprintf()`. // +// In particular, a successful call to `absl::SNPrintF()` writes at most `size` +// bytes of the formatted output to `output`, including a null terminator, and +// returns the number of bytes that would have been written if truncation did +// not occur. In the event of an error, a negative value is returned and `errno` +// is set. +// // Example: // // std::string_view s = "Ulaanbaatar"; diff --git a/absl/strings/string_view.cc b/absl/strings/string_view.cc index dc034a83e..d5e1a3de9 100644 --- a/absl/strings/string_view.cc +++ b/absl/strings/string_view.cc @@ -14,7 +14,7 @@ #include "absl/strings/string_view.h" -#ifndef ABSL_HAVE_STD_STRING_VIEW +#ifndef ABSL_USES_STD_STRING_VIEW #include #include @@ -230,4 +230,4 @@ constexpr string_view::size_type string_view::kMaxSize; } // namespace absl -#endif // ABSL_HAVE_STD_STRING_VIEW +#endif // ABSL_USES_STD_STRING_VIEW diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h index 3438ccc12..07075e80e 100644 --- a/absl/strings/string_view.h +++ b/absl/strings/string_view.h @@ -30,7 +30,7 @@ #include #include "absl/base/config.h" -#ifdef ABSL_HAVE_STD_STRING_VIEW +#ifdef ABSL_USES_STD_STRING_VIEW #include // IWYU pragma: export @@ -38,7 +38,7 @@ namespace absl { using std::string_view; } // namespace absl -#else // ABSL_HAVE_STD_STRING_VIEW +#else // ABSL_USES_STD_STRING_VIEW #if ABSL_HAVE_BUILTIN(__builtin_memcmp) || \ (defined(__GNUC__) && !defined(__clang__)) @@ -580,7 +580,7 @@ std::ostream& operator<<(std::ostream& o, string_view piece); #undef ABSL_INTERNAL_STRING_VIEW_MEMCMP -#endif // ABSL_HAVE_STD_STRING_VIEW +#endif // ABSL_USES_STD_STRING_VIEW namespace absl { diff --git a/absl/strings/string_view_test.cc b/absl/strings/string_view_test.cc index 86f2fbcd0..96dacdf04 100644 --- a/absl/strings/string_view_test.cc +++ b/absl/strings/string_view_test.cc @@ -830,7 +830,7 @@ TEST(StringViewTest, FrontBackSingleChar) { // to the standard, but `absl::string_view` implements a different // behavior for historical reasons. We work around tests that construct // `string_view` from `nullptr` when using libc++. -#if !defined(ABSL_HAVE_STD_STRING_VIEW) || \ +#if !defined(ABSL_USES_STD_STRING_VIEW) || \ (!(defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 9) && \ !defined(_LIBCPP_VERSION) && !defined(_MSC_VER)) #define ABSL_HAVE_STRING_VIEW_FROM_NULLPTR 1 @@ -938,7 +938,7 @@ TEST(StringViewTest, ConstexprCompiles) { #endif constexpr absl::string_view cstr_len("cstr", 4); -#if defined(ABSL_HAVE_STD_STRING_VIEW) +#if defined(ABSL_USES_STD_STRING_VIEW) // In libstdc++ (as of 7.2), `std::string_view::string_view(const char*)` // calls `std::char_traits::length(const char*)` to get the std::string // length, but it is not marked constexpr yet. See GCC bug: @@ -952,7 +952,7 @@ TEST(StringViewTest, ConstexprCompiles) { #define ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR 1 #endif // !__GLIBCXX__ -#else // ABSL_HAVE_STD_STRING_VIEW +#else // ABSL_USES_STD_STRING_VIEW // This duplicates the check for __builtin_strlen in the header. #if ABSL_HAVE_BUILTIN(__builtin_strlen) || \ @@ -967,7 +967,7 @@ TEST(StringViewTest, ConstexprCompiles) { #define ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR 1 #endif -#endif // ABSL_HAVE_STD_STRING_VIEW +#endif // ABSL_USES_STD_STRING_VIEW #ifdef ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR constexpr absl::string_view cstr_strlen("foo"); @@ -1136,7 +1136,7 @@ TEST(HugeStringView, TwoPointTwoGB) { } #endif // THREAD_SANITIZER -#if !defined(NDEBUG) && !defined(ABSL_HAVE_STD_STRING_VIEW) +#if !defined(NDEBUG) && !defined(ABSL_USES_STD_STRING_VIEW) TEST(NonNegativeLenTest, NonNegativeLen) { ABSL_EXPECT_DEATH_IF_SUPPORTED(absl::string_view("xyz", -1), "len <= kMaxSize"); @@ -1152,7 +1152,7 @@ TEST(LenExceedsMaxSizeTest, LenExceedsMaxSize) { ABSL_EXPECT_DEATH_IF_SUPPORTED(absl::string_view("", max_size + 1), "len <= kMaxSize"); } -#endif // !defined(NDEBUG) && !defined(ABSL_HAVE_STD_STRING_VIEW) +#endif // !defined(NDEBUG) && !defined(ABSL_USES_STD_STRING_VIEW) class StringViewStreamTest : public ::testing::Test { public: diff --git a/absl/synchronization/internal/waiter.cc b/absl/synchronization/internal/waiter.cc index d83d8087f..2f41aa5f2 100644 --- a/absl/synchronization/internal/waiter.cc +++ b/absl/synchronization/internal/waiter.cc @@ -161,7 +161,7 @@ bool Waiter::Wait(KernelTimeout t) { void Waiter::Post() { if (futex_.fetch_add(1, std::memory_order_release) == 0) { - // We incremented from 0, need to wake a potential waker. + // We incremented from 0, need to wake a potential waiter. Poke(); } } @@ -210,8 +210,8 @@ void Waiter::Init() { ABSL_RAW_LOG(FATAL, "pthread_cond_init failed: %d", err2); } - waiter_count_.store(0, std::memory_order_relaxed); - wakeup_count_.store(0, std::memory_order_relaxed); + waiter_count_ = 0; + wakeup_count_ = 0; } bool Waiter::Wait(KernelTimeout t) { @@ -221,24 +221,12 @@ bool Waiter::Wait(KernelTimeout t) { } PthreadMutexHolder h(&mu_); - waiter_count_.fetch_add(1, std::memory_order_relaxed); + ++waiter_count_; // Loop until we find a wakeup to consume or timeout. // Note that, since the thread ticker is just reset, we don't need to check // whether the thread is idle on the very first pass of the loop. bool first_pass = true; - while (true) { - int x = wakeup_count_.load(std::memory_order_relaxed); - if (x != 0) { - if (!wakeup_count_.compare_exchange_weak(x, x - 1, - std::memory_order_acquire, - std::memory_order_relaxed)) { - continue; // Raced with someone, retry. - } - // Successfully consumed a wakeup, we're done. - waiter_count_.fetch_sub(1, std::memory_order_relaxed); - return true; - } - + while (wakeup_count_ == 0) { if (!first_pass) MaybeBecomeIdle(); // No wakeups available, time to wait. if (!t.has_timeout()) { @@ -249,34 +237,38 @@ bool Waiter::Wait(KernelTimeout t) { } else { const int err = pthread_cond_timedwait(&cv_, &mu_, &abs_timeout); if (err == ETIMEDOUT) { - waiter_count_.fetch_sub(1, std::memory_order_relaxed); + --waiter_count_; return false; } if (err != 0) { - ABSL_RAW_LOG(FATAL, "pthread_cond_wait failed: %d", err); + ABSL_RAW_LOG(FATAL, "pthread_cond_timedwait failed: %d", err); } } first_pass = false; } + // Consume a wakeup and we're done. + --wakeup_count_; + --waiter_count_; + return true; } void Waiter::Post() { - wakeup_count_.fetch_add(1, std::memory_order_release); - Poke(); + PthreadMutexHolder h(&mu_); + ++wakeup_count_; + InternalCondVarPoke(); } void Waiter::Poke() { - if (waiter_count_.load(std::memory_order_relaxed) == 0) { - return; - } - // Potentially a waker. Take the lock and check again. PthreadMutexHolder h(&mu_); - if (waiter_count_.load(std::memory_order_relaxed) == 0) { - return; - } - const int err = pthread_cond_signal(&cv_); - if (err != 0) { - ABSL_RAW_LOG(FATAL, "pthread_cond_signal failed: %d", err); + InternalCondVarPoke(); +} + +void Waiter::InternalCondVarPoke() { + if (waiter_count_ != 0) { + const int err = pthread_cond_signal(&cv_); + if (ABSL_PREDICT_FALSE(err != 0)) { + ABSL_RAW_LOG(FATAL, "pthread_cond_signal failed: %d", err); + } } } @@ -456,7 +448,7 @@ void Waiter::Poke() { if (waiter_count_.load(std::memory_order_relaxed) == 0) { return; } - // Potentially a waker. Take the lock and check again. + // Potentially a waiter. Take the lock and check again. LockHolder h(WinHelper::GetLock(this)); if (waiter_count_.load(std::memory_order_relaxed) == 0) { return; diff --git a/absl/synchronization/internal/waiter.h b/absl/synchronization/internal/waiter.h index 099935453..c23897007 100644 --- a/absl/synchronization/internal/waiter.h +++ b/absl/synchronization/internal/waiter.h @@ -106,10 +106,13 @@ class Waiter { static_assert(sizeof(int32_t) == sizeof(futex_), "Wrong size for futex"); #elif ABSL_WAITER_MODE == ABSL_WAITER_MODE_CONDVAR + // REQUIRES: mu_ must be held. + void InternalCondVarPoke(); + pthread_mutex_t mu_; pthread_cond_t cv_; - std::atomic waiter_count_; - std::atomic wakeup_count_; // Unclaimed wakeups, written under lock. + int waiter_count_; + int wakeup_count_; // Unclaimed wakeups. #elif ABSL_WAITER_MODE == ABSL_WAITER_MODE_SEM sem_t sem_; diff --git a/absl/synchronization/lifetime_test.cc b/absl/synchronization/lifetime_test.cc index 34b8875b4..cc973a329 100644 --- a/absl/synchronization/lifetime_test.cc +++ b/absl/synchronization/lifetime_test.cc @@ -122,6 +122,11 @@ class OnDestruction { Function fn_; }; +// These tests require that the compiler correctly supports C++11 constant +// initialization... but MSVC has a known regression since v19.10: +// https://developercommunity.visualstudio.com/content/problem/336946/class-with-constexpr-constructor-not-using-static.html +// TODO(epastor): Limit the affected range once MSVC fixes this bug. +#if defined(__clang__) || !(defined(_MSC_VER) && _MSC_VER > 1900) // kConstInit // Test early usage. (Declaration comes first; definitions must appear after // the test runner.) @@ -151,6 +156,7 @@ OnConstruction check_still_locked([]() ABSL_NO_THREAD_SAFETY_ANALYSIS { const_init_sanity_mutex.AssertHeld(); const_init_sanity_mutex.Unlock(); }); +#endif // defined(__clang__) || !(defined(_MSC_VER) && _MSC_VER > 1900) // Test shutdown usage. (Declarations come first; definitions must appear after // the test runner.) diff --git a/absl/time/civil_time.h b/absl/time/civil_time.h index c8166d07c..77c3be2eb 100644 --- a/absl/time/civil_time.h +++ b/absl/time/civil_time.h @@ -519,7 +519,7 @@ namespace time_internal { // For functions found via ADL on civil-time tags. // // Example: // -// absl::CivilDay d = absl::CivilDay("1969-07-20"); +// absl::CivilDay d = absl::CivilDay(1969, 7, 20); // std::cout << "Date is: " << d << "\n"; // std::ostream& operator<<(std::ostream& os, CivilYear y); diff --git a/absl/time/duration.cc b/absl/time/duration.cc index 9a8768113..f0b4631d6 100644 --- a/absl/time/duration.cc +++ b/absl/time/duration.cc @@ -197,11 +197,11 @@ inline int64_t DecodeTwosComp(uint64_t v) { return absl::bit_cast(v); } // double as overflow cases. inline bool SafeAddRepHi(double a_hi, double b_hi, Duration* d) { double c = a_hi + b_hi; - if (c >= kint64max) { + if (c >= static_cast(kint64max)) { *d = InfiniteDuration(); return false; } - if (c <= kint64min) { + if (c <= static_cast(kint64min)) { *d = -InfiniteDuration(); return false; } diff --git a/absl/time/time.h b/absl/time/time.h index 0b7312ee9..46ac26b3c 100644 --- a/absl/time/time.h +++ b/absl/time/time.h @@ -422,7 +422,9 @@ Duration Milliseconds(T n) { template = 0> Duration Seconds(T n) { if (n >= 0) { // Note: `NaN >= 0` is false. - if (n >= (std::numeric_limits::max)()) return InfiniteDuration(); + if (n >= static_cast((std::numeric_limits::max)())) { + return InfiniteDuration(); + } return time_internal::MakePosDoubleDuration(n); } else { if (std::isnan(n)) diff --git a/absl/types/any.h b/absl/types/any.h index 507c8b2cc..f79676949 100644 --- a/absl/types/any.h +++ b/absl/types/any.h @@ -56,7 +56,7 @@ #include "absl/base/config.h" #include "absl/utility/utility.h" -#ifdef ABSL_HAVE_STD_ANY +#ifdef ABSL_USES_STD_ANY #include // IWYU pragma: export @@ -67,7 +67,7 @@ using std::bad_any_cast; using std::make_any; } // namespace absl -#else // ABSL_HAVE_STD_ANY +#else // ABSL_USES_STD_ANY #include #include @@ -538,6 +538,6 @@ T* any_cast(any* operand) noexcept { #undef ABSL_ANY_DETAIL_HAS_RTTI -#endif // ABSL_HAVE_STD_ANY +#endif // ABSL_USES_STD_ANY #endif // ABSL_TYPES_ANY_H_ diff --git a/absl/types/any_exception_safety_test.cc b/absl/types/any_exception_safety_test.cc index 17d7f5d77..31c114013 100644 --- a/absl/types/any_exception_safety_test.cc +++ b/absl/types/any_exception_safety_test.cc @@ -18,7 +18,7 @@ // This test is a no-op when absl::any is an alias for std::any and when // exceptions are not enabled. -#if !defined(ABSL_HAVE_STD_ANY) && defined(ABSL_HAVE_EXCEPTIONS) +#if !defined(ABSL_USES_STD_ANY) && defined(ABSL_HAVE_EXCEPTIONS) #include #include @@ -170,4 +170,4 @@ TEST(AnyExceptionSafety, Emplace) { } // namespace -#endif // #if !defined(ABSL_HAVE_STD_ANY) && defined(ABSL_HAVE_EXCEPTIONS) +#endif // #if !defined(ABSL_USES_STD_ANY) && defined(ABSL_HAVE_EXCEPTIONS) diff --git a/absl/types/any_test.cc b/absl/types/any_test.cc index 4a848ae4a..70e4ba22b 100644 --- a/absl/types/any_test.cc +++ b/absl/types/any_test.cc @@ -15,7 +15,7 @@ #include "absl/types/any.h" // This test is a no-op when absl::any is an alias for std::any. -#if !defined(ABSL_HAVE_STD_ANY) +#if !defined(ABSL_USES_STD_ANY) #include #include @@ -642,7 +642,7 @@ TEST(AnyTest, ConversionConstructionCausesOneCopy) { // Tests for Exception Behavior // ////////////////////////////////// -#if defined(ABSL_HAVE_STD_ANY) +#if defined(ABSL_USES_STD_ANY) // If using a std `any` implementation, we can't check for a specific message. #define ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(...) \ @@ -656,7 +656,7 @@ TEST(AnyTest, ConversionConstructionCausesOneCopy) { ABSL_BASE_INTERNAL_EXPECT_FAIL((__VA_ARGS__), absl::bad_any_cast, \ "Bad any cast") -#endif // defined(ABSL_HAVE_STD_ANY) +#endif // defined(ABSL_USES_STD_ANY) TEST(AnyTest, ThrowBadAlloc) { { @@ -764,7 +764,7 @@ TEST(AnyTest, FailedEmplace) { BadCopyable bad; absl::any target(absl::in_place_type); ABSL_ANY_TEST_EXPECT_BAD_COPY(target.emplace(bad)); -#if defined(ABSL_HAVE_STD_ANY) && defined(__GLIBCXX__) +#if defined(ABSL_USES_STD_ANY) && defined(__GLIBCXX__) // libstdc++ std::any::emplace() implementation (as of 7.2) has a bug: if an // exception is thrown, *this contains a value. #define ABSL_GLIBCXX_ANY_EMPLACE_EXCEPTION_BUG 1 @@ -778,4 +778,4 @@ TEST(AnyTest, FailedEmplace) { } // namespace -#endif // #if !defined(ABSL_HAVE_STD_ANY) +#endif // #if !defined(ABSL_USES_STD_ANY) diff --git a/absl/types/bad_any_cast.cc b/absl/types/bad_any_cast.cc index 505919a55..2a5381266 100644 --- a/absl/types/bad_any_cast.cc +++ b/absl/types/bad_any_cast.cc @@ -14,7 +14,7 @@ #include "absl/types/bad_any_cast.h" -#ifndef ABSL_HAVE_STD_ANY +#ifndef ABSL_USES_STD_ANY #include @@ -41,4 +41,4 @@ void ThrowBadAnyCast() { } // namespace any_internal } // namespace absl -#endif // ABSL_HAVE_STD_ANY +#endif // ABSL_USES_STD_ANY diff --git a/absl/types/bad_any_cast.h b/absl/types/bad_any_cast.h index 8d020ede4..6a53c0108 100644 --- a/absl/types/bad_any_cast.h +++ b/absl/types/bad_any_cast.h @@ -25,7 +25,7 @@ #include "absl/base/config.h" -#ifdef ABSL_HAVE_STD_ANY +#ifdef ABSL_USES_STD_ANY #include @@ -33,7 +33,7 @@ namespace absl { using std::bad_any_cast; } // namespace absl -#else // ABSL_HAVE_STD_ANY +#else // ABSL_USES_STD_ANY namespace absl { @@ -66,6 +66,6 @@ namespace any_internal { } // namespace any_internal } // namespace absl -#endif // ABSL_HAVE_STD_ANY +#endif // ABSL_USES_STD_ANY #endif // ABSL_TYPES_BAD_ANY_CAST_H_ diff --git a/absl/types/bad_optional_access.cc b/absl/types/bad_optional_access.cc index a791c7c21..d9ec21bf4 100644 --- a/absl/types/bad_optional_access.cc +++ b/absl/types/bad_optional_access.cc @@ -14,7 +14,7 @@ #include "absl/types/bad_optional_access.h" -#ifndef ABSL_HAVE_STD_OPTIONAL +#ifndef ABSL_USES_STD_OPTIONAL #include @@ -43,4 +43,4 @@ void throw_bad_optional_access() { } // namespace optional_internal } // namespace absl -#endif // ABSL_HAVE_STD_OPTIONAL +#endif // ABSL_USES_STD_OPTIONAL diff --git a/absl/types/bad_optional_access.h b/absl/types/bad_optional_access.h index add5c452c..32dd6a91e 100644 --- a/absl/types/bad_optional_access.h +++ b/absl/types/bad_optional_access.h @@ -25,7 +25,7 @@ #include "absl/base/config.h" -#ifdef ABSL_HAVE_STD_OPTIONAL +#ifdef ABSL_USES_STD_OPTIONAL #include @@ -33,7 +33,7 @@ namespace absl { using std::bad_optional_access; } // namespace absl -#else // ABSL_HAVE_STD_OPTIONAL +#else // ABSL_USES_STD_OPTIONAL namespace absl { @@ -69,6 +69,6 @@ namespace optional_internal { } // namespace optional_internal } // namespace absl -#endif // ABSL_HAVE_STD_OPTIONAL +#endif // ABSL_USES_STD_OPTIONAL #endif // ABSL_TYPES_BAD_OPTIONAL_ACCESS_H_ diff --git a/absl/types/bad_variant_access.cc b/absl/types/bad_variant_access.cc index a4325c8df..dbaea9e9d 100644 --- a/absl/types/bad_variant_access.cc +++ b/absl/types/bad_variant_access.cc @@ -14,7 +14,7 @@ #include "absl/types/bad_variant_access.h" -#ifndef ABSL_HAVE_STD_VARIANT +#ifndef ABSL_USES_STD_VARIANT #include #include @@ -59,4 +59,4 @@ void Rethrow() { } // namespace variant_internal } // namespace absl -#endif // ABSL_HAVE_STD_VARIANT +#endif // ABSL_USES_STD_VARIANT diff --git a/absl/types/bad_variant_access.h b/absl/types/bad_variant_access.h index 637db4355..6935d01b9 100644 --- a/absl/types/bad_variant_access.h +++ b/absl/types/bad_variant_access.h @@ -25,7 +25,7 @@ #include "absl/base/config.h" -#ifdef ABSL_HAVE_STD_VARIANT +#ifdef ABSL_USES_STD_VARIANT #include @@ -33,7 +33,7 @@ namespace absl { using std::bad_variant_access; } // namespace absl -#else // ABSL_HAVE_STD_VARIANT +#else // ABSL_USES_STD_VARIANT namespace absl { @@ -73,6 +73,6 @@ namespace variant_internal { } // namespace variant_internal } // namespace absl -#endif // ABSL_HAVE_STD_VARIANT +#endif // ABSL_USES_STD_VARIANT #endif // ABSL_TYPES_BAD_VARIANT_ACCESS_H_ diff --git a/absl/types/internal/variant.h b/absl/types/internal/variant.h index 19de2e137..58b385921 100644 --- a/absl/types/internal/variant.h +++ b/absl/types/internal/variant.h @@ -37,7 +37,7 @@ #include "absl/types/bad_variant_access.h" #include "absl/utility/utility.h" -#if !defined(ABSL_HAVE_STD_VARIANT) +#if !defined(ABSL_USES_STD_VARIANT) namespace absl { @@ -1640,5 +1640,5 @@ struct VariantHashBase // IWYU pragma: export @@ -50,7 +50,7 @@ using std::nullopt_t; using std::nullopt; } // namespace absl -#else // ABSL_HAVE_STD_OPTIONAL +#else // ABSL_USES_STD_OPTIONAL #include #include @@ -767,6 +767,6 @@ struct hash > #undef ABSL_MSVC_CONSTEXPR_BUG_IN_UNION_LIKE_CLASS -#endif // ABSL_HAVE_STD_OPTIONAL +#endif // ABSL_USES_STD_OPTIONAL #endif // ABSL_TYPES_OPTIONAL_H_ diff --git a/absl/types/optional_exception_safety_test.cc b/absl/types/optional_exception_safety_test.cc index f99e35c05..0f7fae6cb 100644 --- a/absl/types/optional_exception_safety_test.cc +++ b/absl/types/optional_exception_safety_test.cc @@ -18,7 +18,7 @@ // This test is a no-op when absl::optional is an alias for std::optional and // when exceptions are not enabled. -#if !defined(ABSL_HAVE_STD_OPTIONAL) && defined(ABSL_HAVE_EXCEPTIONS) +#if !defined(ABSL_USES_STD_OPTIONAL) && defined(ABSL_HAVE_EXCEPTIONS) #include "gtest/gtest.h" #include "absl/base/internal/exception_safety_testing.h" @@ -287,4 +287,4 @@ TEST(OptionalExceptionSafety, NothrowMoveAssign) { } // namespace absl -#endif // #if !defined(ABSL_HAVE_STD_OPTIONAL) && defined(ABSL_HAVE_EXCEPTIONS) +#endif // #if !defined(ABSL_USES_STD_OPTIONAL) && defined(ABSL_HAVE_EXCEPTIONS) diff --git a/absl/types/optional_test.cc b/absl/types/optional_test.cc index 35efa8635..47d5c8a29 100644 --- a/absl/types/optional_test.cc +++ b/absl/types/optional_test.cc @@ -15,7 +15,7 @@ #include "absl/types/optional.h" // This test is a no-op when absl::optional is an alias for std::optional. -#if !defined(ABSL_HAVE_STD_OPTIONAL) +#if !defined(ABSL_USES_STD_OPTIONAL) #include #include @@ -224,7 +224,7 @@ TEST(optionalTest, CopyConstructor) { EXPECT_FALSE( absl::is_trivially_copy_constructible>::value); -#if defined(ABSL_HAVE_STD_OPTIONAL) && defined(__GLIBCXX__) +#if defined(ABSL_USES_STD_OPTIONAL) && defined(__GLIBCXX__) // libstdc++ std::optional implementation (as of 7.2) has a bug: when T is // trivially copyable, optional is not trivially copyable (due to one of // its base class is unconditionally nontrivial). @@ -279,7 +279,7 @@ TEST(optionalTest, CopyConstructor) { // std::optional when T is volatile-qualified. So skipping this test. // Bug report: // https://connect.microsoft.com/VisualStudio/feedback/details/3142534 -#if defined(ABSL_HAVE_STD_OPTIONAL) && defined(_MSC_VER) && _MSC_VER >= 1911 +#if defined(ABSL_USES_STD_OPTIONAL) && defined(_MSC_VER) && _MSC_VER >= 1911 #define ABSL_MSVC_OPTIONAL_VOLATILE_COPY_BUG 1 #endif #ifndef ABSL_MSVC_OPTIONAL_VOLATILE_COPY_BUG @@ -305,7 +305,7 @@ TEST(optionalTest, MoveConstructor) { EXPECT_FALSE(std::is_move_constructible>::value); // test noexcept EXPECT_TRUE(std::is_nothrow_move_constructible>::value); -#ifndef ABSL_HAVE_STD_OPTIONAL +#ifndef ABSL_USES_STD_OPTIONAL EXPECT_EQ( absl::default_allocator_is_nothrow::value, std::is_nothrow_move_constructible>::value); @@ -639,7 +639,7 @@ TEST(optionalTest, CopyAssignment) { EXPECT_FALSE(absl::is_trivially_copy_assignable::value); // std::optional doesn't support volatile nontrivial types. -#ifndef ABSL_HAVE_STD_OPTIONAL +#ifndef ABSL_USES_STD_OPTIONAL { StructorListener listener; Listenable::listener = &listener; @@ -658,7 +658,7 @@ TEST(optionalTest, CopyAssignment) { EXPECT_EQ(1, listener.destruct); EXPECT_EQ(1, listener.volatile_copy_assign); } -#endif // ABSL_HAVE_STD_OPTIONAL +#endif // ABSL_USES_STD_OPTIONAL } TEST(optionalTest, MoveAssignment) { @@ -682,7 +682,7 @@ TEST(optionalTest, MoveAssignment) { EXPECT_EQ(1, listener.move_assign); } // std::optional doesn't support volatile nontrivial types. -#ifndef ABSL_HAVE_STD_OPTIONAL +#ifndef ABSL_USES_STD_OPTIONAL { StructorListener listener; Listenable::listener = &listener; @@ -702,7 +702,7 @@ TEST(optionalTest, MoveAssignment) { EXPECT_EQ(1, listener.destruct); EXPECT_EQ(1, listener.volatile_move_assign); } -#endif // ABSL_HAVE_STD_OPTIONAL +#endif // ABSL_USES_STD_OPTIONAL EXPECT_FALSE(absl::is_move_assignable>::value); EXPECT_TRUE(absl::is_move_assignable>::value); EXPECT_TRUE(absl::is_move_assignable>::value); @@ -1560,7 +1560,7 @@ TEST(optionalTest, NoExcept) { static_assert( std::is_nothrow_move_constructible>::value, ""); -#ifndef ABSL_HAVE_STD_OPTIONAL +#ifndef ABSL_USES_STD_OPTIONAL static_assert(absl::default_allocator_is_nothrow::value == std::is_nothrow_move_constructible< absl::optional>::value, @@ -1658,4 +1658,4 @@ TEST(optionalTest, InPlaceTSFINAEBug) { } // namespace -#endif // #if !defined(ABSL_HAVE_STD_OPTIONAL) +#endif // #if !defined(ABSL_USES_STD_OPTIONAL) diff --git a/absl/types/variant.h b/absl/types/variant.h index 7ef7f88ca..f3558703a 100644 --- a/absl/types/variant.h +++ b/absl/types/variant.h @@ -45,7 +45,7 @@ #include "absl/base/config.h" #include "absl/utility/utility.h" -#ifdef ABSL_HAVE_STD_VARIANT +#ifdef ABSL_USES_STD_VARIANT #include // IWYU pragma: export @@ -64,7 +64,7 @@ using std::variant_size_v; using std::visit; } // namespace absl -#else // ABSL_HAVE_STD_VARIANT +#else // ABSL_USES_STD_VARIANT #include #include @@ -812,7 +812,7 @@ struct hash> } // namespace std -#endif // ABSL_HAVE_STD_VARIANT +#endif // ABSL_USES_STD_VARIANT namespace absl { namespace variant_internal { diff --git a/absl/types/variant_exception_safety_test.cc b/absl/types/variant_exception_safety_test.cc index fd7e6c7fe..b486a71e5 100644 --- a/absl/types/variant_exception_safety_test.cc +++ b/absl/types/variant_exception_safety_test.cc @@ -18,7 +18,7 @@ // This test is a no-op when absl::variant is an alias for std::variant and when // exceptions are not enabled. -#if !defined(ABSL_HAVE_STD_VARIANT) && defined(ABSL_HAVE_EXCEPTIONS) +#if !defined(ABSL_USES_STD_VARIANT) && defined(ABSL_HAVE_EXCEPTIONS) #include #include @@ -237,7 +237,7 @@ TEST(VariantExceptionSafetyTest, CopyAssign) { } // libstdc++ std::variant has bugs on copy assignment regarding exception // safety. -#if !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) +#if !(defined(ABSL_USES_STD_VARIANT) && defined(__GLIBCXX__)) // index() != j // if is_nothrow_copy_constructible_v or // !is_nothrow_move_constructible is true, equivalent to @@ -268,7 +268,7 @@ TEST(VariantExceptionSafetyTest, CopyAssign) { .Test()); EXPECT_FALSE(tester.WithContracts(strong_guarantee).Test()); } -#endif // !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) +#endif // !(defined(ABSL_USES_STD_VARIANT) && defined(__GLIBCXX__)) { // is_nothrow_copy_constructible_v == false && // is_nothrow_move_constructible_v == true @@ -325,7 +325,7 @@ TEST(VariantExceptionSafetyTest, MoveAssign) { // The fix is targeted for gcc-9. // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87431#c7 // https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=267614 -#if !(defined(ABSL_HAVE_STD_VARIANT) && \ +#if !(defined(ABSL_USES_STD_VARIANT) && \ defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE == 8) // - otherwise (index() != j), equivalent to // emplace(get(std::move(rhs))) @@ -342,7 +342,7 @@ TEST(VariantExceptionSafetyTest, MoveAssign) { auto copy = rhs; *lhs = std::move(copy); })); -#endif // !(defined(ABSL_HAVE_STD_VARIANT) && +#endif // !(defined(ABSL_USES_STD_VARIANT) && // defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE == 8) } } @@ -445,7 +445,7 @@ TEST(VariantExceptionSafetyTest, ValueAssign) { // and operator=(variant&&) invokes Tj's move ctor which doesn't throw. // libstdc++ std::variant has bugs on conversion assignment regarding // exception safety. -#if !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) +#if !(defined(ABSL_USES_STD_VARIANT) && defined(__GLIBCXX__)) { MoveNothrow rhs; EXPECT_TRUE(MakeExceptionSafetyTester() @@ -453,7 +453,7 @@ TEST(VariantExceptionSafetyTest, ValueAssign) { .WithContracts(VariantInvariants, strong_guarantee) .Test([&rhs](ThrowingVariant* lhs) { *lhs = rhs; })); } -#endif // !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) +#endif // !(defined(ABSL_USES_STD_VARIANT) && defined(__GLIBCXX__)) } TEST(VariantExceptionSafetyTest, Emplace) { @@ -527,4 +527,4 @@ TEST(VariantExceptionSafetyTest, Swap) { #endif // !defined(ABSL_INTERNAL_MSVC_2017_DBG_MODE) -#endif // #if !defined(ABSL_HAVE_STD_VARIANT) && defined(ABSL_HAVE_EXCEPTIONS) +#endif // #if !defined(ABSL_USES_STD_VARIANT) && defined(ABSL_HAVE_EXCEPTIONS) diff --git a/absl/types/variant_test.cc b/absl/types/variant_test.cc index b59127457..2913775a4 100644 --- a/absl/types/variant_test.cc +++ b/absl/types/variant_test.cc @@ -20,7 +20,7 @@ #include "absl/types/variant.h" // This test is a no-op when absl::variant is an alias for std::variant. -#if !defined(ABSL_HAVE_STD_VARIANT) +#if !defined(ABSL_USES_STD_VARIANT) #include #include @@ -842,7 +842,7 @@ TEST(VariantTest, TestBackupAssign) { } // libstdc++ doesn't pass this test -#if !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) +#if !(defined(ABSL_USES_STD_VARIANT) && defined(__GLIBCXX__)) EXPECT_EQ(3, counter[0]); EXPECT_EQ(2, counter[1]); EXPECT_EQ(2, counter[2]); @@ -1933,7 +1933,7 @@ TEST(VariantTest, VisitReferenceWrapper) { } // libstdc++ std::variant doesn't support the INVOKE semantics. -#if !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) +#if !(defined(ABSL_USES_STD_VARIANT) && defined(__GLIBCXX__)) TEST(VariantTest, VisitMemberFunction) { absl::variant> p(absl::make_unique()); absl::variant> cp( @@ -1957,7 +1957,7 @@ TEST(VariantTest, VisitDataMember) { EXPECT_EQ(42, absl::visit(&Class::member, cp)); } -#endif // !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) +#endif // !(defined(ABSL_USES_STD_VARIANT) && defined(__GLIBCXX__)) ///////////////////////// // [variant.monostate] // @@ -2035,7 +2035,7 @@ TEST(VariantTest, NonmemberSwap) { std::swap(a, b); EXPECT_THAT(a, VariantWith(v2)); EXPECT_THAT(b, VariantWith(v1)); -#ifndef ABSL_HAVE_STD_VARIANT +#ifndef ABSL_USES_STD_VARIANT EXPECT_FALSE(absl::get(a).special_swap); #endif @@ -2083,7 +2083,7 @@ TEST(VariantTest, Hash) { // MSVC std::hash does not use the index, thus produce the same // result on the same value as different alternative. -#if !(defined(_MSC_VER) && defined(ABSL_HAVE_STD_VARIANT)) +#if !(defined(_MSC_VER) && defined(ABSL_USES_STD_VARIANT)) { // same value as different alternative variant v0(in_place_index<0>, 42); @@ -2091,7 +2091,7 @@ TEST(VariantTest, Hash) { std::hash> hash; EXPECT_NE(hash(v0), hash(v1)); } -#endif // !(defined(_MSC_VER) && defined(ABSL_HAVE_STD_VARIANT)) +#endif // !(defined(_MSC_VER) && defined(ABSL_USES_STD_VARIANT)) { std::hash> hash; @@ -2118,7 +2118,7 @@ TEST(VariantTest, Hash) { //////////////////////////////////////// // Test that a set requiring a basic type conversion works correctly -#if !defined(ABSL_HAVE_STD_VARIANT) +#if !defined(ABSL_USES_STD_VARIANT) TEST(VariantTest, TestConvertingSet) { typedef variant Variant; Variant v(1.0); @@ -2128,7 +2128,7 @@ TEST(VariantTest, TestConvertingSet) { ASSERT_TRUE(nullptr != absl::get_if(&v)); EXPECT_DOUBLE_EQ(2, absl::get(v)); } -#endif // ABSL_HAVE_STD_VARIANT +#endif // ABSL_USES_STD_VARIANT // Test that a vector of variants behaves reasonably. TEST(VariantTest, Container) { @@ -2280,7 +2280,7 @@ struct Convertible2 { }; TEST(VariantTest, TestRvalueConversion) { -#if !defined(ABSL_HAVE_STD_VARIANT) +#if !defined(ABSL_USES_STD_VARIANT) variant var( ConvertVariantTo>( variant(0))); @@ -2313,7 +2313,7 @@ TEST(VariantTest, TestRvalueConversion) { variant2 = ConvertVariantTo>(variant(42)); ASSERT_TRUE(absl::holds_alternative(variant2)); EXPECT_EQ(42, absl::get(variant2)); -#endif // !ABSL_HAVE_STD_VARIANT +#endif // !ABSL_USES_STD_VARIANT variant variant3( ConvertVariantTo>( @@ -2326,7 +2326,7 @@ TEST(VariantTest, TestRvalueConversion) { } TEST(VariantTest, TestLvalueConversion) { -#if !defined(ABSL_HAVE_STD_VARIANT) +#if !defined(ABSL_USES_STD_VARIANT) variant source1 = 0; variant destination( ConvertVariantTo>(source1)); @@ -2428,7 +2428,7 @@ TEST(VariantTest, DoesNotMoveFromLvalues) { } TEST(VariantTest, TestRvalueConversionViaConvertVariantTo) { -#if !defined(ABSL_HAVE_STD_VARIANT) +#if !defined(ABSL_USES_STD_VARIANT) variant var( ConvertVariantTo>( variant(3))); @@ -2467,7 +2467,7 @@ TEST(VariantTest, TestRvalueConversionViaConvertVariantTo) { } TEST(VariantTest, TestLvalueConversionViaConvertVariantTo) { -#if !defined(ABSL_HAVE_STD_VARIANT) +#if !defined(ABSL_USES_STD_VARIANT) variant source1 = 3; variant destination( ConvertVariantTo>(source1)); @@ -2499,7 +2499,7 @@ TEST(VariantTest, TestLvalueConversionViaConvertVariantTo) { variant source6(42); variant2 = ConvertVariantTo>(source6); EXPECT_THAT(absl::get_if(&variant2), Pointee(42)); -#endif // !ABSL_HAVE_STD_VARIANT +#endif // !ABSL_USES_STD_VARIANT variant source7((Convertible1())); variant variant3( @@ -2533,7 +2533,7 @@ TEST(VariantTest, TestMoveConversionViaConvertVariantTo) { // standard and we know that libstdc++ variant doesn't have this feature. // For more details see the paper: // http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0602r0.html -#if !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) +#if !(defined(ABSL_USES_STD_VARIANT) && defined(__GLIBCXX__)) #define ABSL_VARIANT_PROPAGATE_COPY_MOVE_TRIVIALITY 1 #endif @@ -2711,4 +2711,4 @@ TEST(VariantTest, MoveCtorBug) { } // namespace } // namespace absl -#endif // #if !defined(ABSL_HAVE_STD_VARIANT) +#endif // #if !defined(ABSL_USES_STD_VARIANT) diff --git a/absl/utility/utility.h b/absl/utility/utility.h index eef8fb41f..5a98c2c39 100644 --- a/absl/utility/utility.h +++ b/absl/utility/utility.h @@ -158,12 +158,12 @@ using index_sequence_for = make_index_sequence; // Tag types -#ifdef ABSL_HAVE_STD_OPTIONAL +#ifdef ABSL_USES_STD_OPTIONAL using std::in_place_t; using std::in_place; -#else // ABSL_HAVE_STD_OPTIONAL +#else // ABSL_USES_STD_OPTIONAL // in_place_t // @@ -174,9 +174,9 @@ struct in_place_t {}; ABSL_INTERNAL_INLINE_CONSTEXPR(in_place_t, in_place, {}); -#endif // ABSL_HAVE_STD_OPTIONAL +#endif // ABSL_USES_STD_OPTIONAL -#if defined(ABSL_HAVE_STD_ANY) || defined(ABSL_HAVE_STD_VARIANT) +#if defined(ABSL_USES_STD_ANY) || defined(ABSL_USES_STD_VARIANT) using std::in_place_type; using std::in_place_type_t; #else @@ -191,9 +191,9 @@ using in_place_type_t = void (*)(utility_internal::InPlaceTypeTag); template void in_place_type(utility_internal::InPlaceTypeTag) {} -#endif // ABSL_HAVE_STD_ANY || ABSL_HAVE_STD_VARIANT +#endif // ABSL_USES_STD_ANY || ABSL_USES_STD_VARIANT -#ifdef ABSL_HAVE_STD_VARIANT +#ifdef ABSL_USES_STD_VARIANT using std::in_place_index; using std::in_place_index_t; #else @@ -208,7 +208,7 @@ using in_place_index_t = void (*)(utility_internal::InPlaceIndexTag); template void in_place_index(utility_internal::InPlaceIndexTag) {} -#endif // ABSL_HAVE_STD_VARIANT +#endif // ABSL_USES_STD_VARIANT // Constexpr move and forward