diff options
Diffstat (limited to 'absl')
40 files changed, 451 insertions, 184 deletions
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index ffeca630706e..6fc712d968f3 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 2698213c566d..9550cdb2db49 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 24851fa33ce4..46a84f1a76f6 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -63,6 +63,7 @@ #include <TargetConditionals.h> #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<SomeStruct> 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 b43c9a46ee35..8233cb52433b 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 <stdlib.h> // NOLINT(build/include) -#elif defined(__APPLE__) -// macOS / Darwin features -#include <libkern/OSByteOrder.h> #elif defined(__FreeBSD__) #include <sys/endian.h> #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 000000000000..3961e63f4e2a --- /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 6cff1a25716f..02d1f879dae1 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<int, absl::any> 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 7d08f7e306e4..f678c88dafd5 100644 --- a/absl/container/internal/inlined_vector.h +++ b/absl/container/internal/inlined_vector.h @@ -471,12 +471,9 @@ auto Storage<T, N, A>::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<T, N, A>::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<T, N, A>::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<T, N, A>::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>(args)...); if (allocation_tx.DidAllocate()) { @@ -707,8 +701,7 @@ auto Storage<T, N, A>::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<T, N, A>::EmplaceBack(Args&&... args) -> reference { } AddSize(1); - return *(construct_data + storage_view.size); + return *last_ptr; } template <typename T, size_t N, typename A> @@ -793,9 +786,7 @@ auto Storage<T, N, A>::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 9992ba4b8ac0..9079a73e52a6 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 76959cdef602..d57a87923136 100644 --- a/absl/meta/type_traits.h +++ b/absl/meta/type_traits.h @@ -145,6 +145,18 @@ using IsMoveAssignableImpl = decltype(std::declval<T&>() = std::declval<T&&>()); } // 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 <typename T> +using is_copy_assignable = std::is_copy_assignable<T>; + +template <typename T> +using is_move_assignable = std::is_move_assignable<T>; + +#else + template <typename T> 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 d9de99019ce0..698027fc6e0d 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<uint32_t>(0, 100)(rbg); - std::uniform_real_distribution<float>()(rbg); - std::bernoulli_distribution(0.2)(rbg); + // Cast to void to suppress [[nodiscard]] warnings + static_cast<void>(std::uniform_int_distribution<uint32_t>(0, 100)(rbg)); + static_cast<void>(std::uniform_real_distribution<float>()(rbg)); + static_cast<void>(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 956a69070ccd..de58bdbe14ca 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<IntType>::Generate( const double r = std::pow(p.base(), d); const double s = (r * p.base()) - 1.0; - base_e = (r > (std::numeric_limits<unsigned_type>::max)()) - ? (std::numeric_limits<unsigned_type>::max)() - : static_cast<unsigned_type>(r); - - top_e = (s > (std::numeric_limits<unsigned_type>::max)()) - ? (std::numeric_limits<unsigned_type>::max)() - : static_cast<unsigned_type>(s); + base_e = + (r > static_cast<double>((std::numeric_limits<unsigned_type>::max)())) + ? (std::numeric_limits<unsigned_type>::max)() + : static_cast<unsigned_type>(r); + + top_e = + (s > static_cast<double>((std::numeric_limits<unsigned_type>::max)())) + ? (std::numeric_limits<unsigned_type>::max)() + : static_cast<unsigned_type>(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 745de67ad86d..9b8ec89a8941 100644 --- a/absl/strings/numbers.h +++ b/absl/strings/numbers.h @@ -37,7 +37,14 @@ #include <type_traits> #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 d587789972e4..4bd56f5f4386 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 607e2bcaae16..c11c93a24837 100644 --- a/absl/strings/str_format.h +++ b/absl/strings/str_format.h @@ -400,6 +400,12 @@ int FPrintF(std::FILE* output, const FormatSpec<Args...>& 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 dc034a83eea8..d5e1a3de9ff3 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 <algorithm> #include <climits> @@ -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 3438ccc12a7d..07075e80ec64 100644 --- a/absl/strings/string_view.h +++ b/absl/strings/string_view.h @@ -30,7 +30,7 @@ #include <algorithm> #include "absl/base/config.h" -#ifdef ABSL_HAVE_STD_STRING_VIEW +#ifdef ABSL_USES_STD_STRING_VIEW #include <string_view> // 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 86f2fbcd003a..96dacdf048cf 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<char>::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 d83d8087f8d5..2f41aa5f2b44 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 099935453bee..c23897007e70 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<int> waiter_count_; - std::atomic<int> 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 34b8875b4b70..cc973a329071 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 c8166d07c94e..77c3be2eba6b 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 9a8768113f31..f0b4631d6fa9 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<int64_t>(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<double>(kint64max)) { *d = InfiniteDuration(); return false; } - if (c <= kint64min) { + if (c <= static_cast<double>(kint64min)) { *d = -InfiniteDuration(); return false; } diff --git a/absl/time/time.h b/absl/time/time.h index 0b7312ee983d..46ac26b3c0d2 100644 --- a/absl/time/time.h +++ b/absl/time/time.h @@ -422,7 +422,9 @@ Duration Milliseconds(T n) { template <typename T, time_internal::EnableIfFloat<T> = 0> Duration Seconds(T n) { if (n >= 0) { // Note: `NaN >= 0` is false. - if (n >= (std::numeric_limits<int64_t>::max)()) return InfiniteDuration(); + if (n >= static_cast<T>((std::numeric_limits<int64_t>::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 507c8b2cc4f1..f79676949d3d 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 <any> // 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 <algorithm> #include <cstddef> @@ -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 17d7f5d77813..31c1140135f0 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 <typeinfo> #include <vector> @@ -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 4a848ae4ae8f..70e4ba22b12b 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 <initializer_list> #include <type_traits> @@ -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<int>); ABSL_ANY_TEST_EXPECT_BAD_COPY(target.emplace<BadCopyable>(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 505919a55831..2a5381266452 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 <cstdlib> @@ -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 8d020ede466b..6a53c0108100 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 <any> @@ -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 a791c7c21da8..d9ec21bf42b9 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 <cstdlib> @@ -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 add5c452cd50..32dd6a91ea65 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 <optional> @@ -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 a4325c8df7db..dbaea9e9d1db 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 <cstdlib> #include <stdexcept> @@ -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 637db4355053..6935d01b99f7 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 <variant> @@ -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 19de2e137593..58b385921f59 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<Variant, } // namespace variant_internal } // namespace absl -#endif // !defined(ABSL_HAVE_STD_VARIANT) +#endif // !defined(ABSL_USES_STD_VARIANT) #endif // ABSL_TYPES_variant_internal_H_ diff --git a/absl/types/optional.h b/absl/types/optional.h index ed8faf97a1d4..14032598d9b0 100644 --- a/absl/types/optional.h +++ b/absl/types/optional.h @@ -38,7 +38,7 @@ #include "absl/base/config.h" // TODO(calabrese) IWYU removal? #include "absl/utility/utility.h" -#ifdef ABSL_HAVE_STD_OPTIONAL +#ifdef ABSL_USES_STD_OPTIONAL #include <optional> // 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 <cassert> #include <functional> @@ -767,6 +767,6 @@ struct hash<absl::optional<T> > #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 f99e35c05447..0f7fae6cb4cf 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 35efa8635077..47d5c8a29e00 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 <string> #include <type_traits> @@ -224,7 +224,7 @@ TEST(optionalTest, CopyConstructor) { EXPECT_FALSE( absl::is_trivially_copy_constructible<absl::optional<Copyable>>::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<T> 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<absl::optional<NonMovable>>::value); // test noexcept EXPECT_TRUE(std::is_nothrow_move_constructible<absl::optional<int>>::value); -#ifndef ABSL_HAVE_STD_OPTIONAL +#ifndef ABSL_USES_STD_OPTIONAL EXPECT_EQ( absl::default_allocator_is_nothrow::value, std::is_nothrow_move_constructible<absl::optional<MoveableThrow>>::value); @@ -639,7 +639,7 @@ TEST(optionalTest, CopyAssignment) { EXPECT_FALSE(absl::is_trivially_copy_assignable<NonTrivial>::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<absl::optional<const int>>::value); EXPECT_TRUE(absl::is_move_assignable<absl::optional<Copyable>>::value); EXPECT_TRUE(absl::is_move_assignable<absl::optional<MoveableThrow>>::value); @@ -1560,7 +1560,7 @@ TEST(optionalTest, NoExcept) { static_assert( std::is_nothrow_move_constructible<absl::optional<MoveMeNoThrow>>::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<MoveMeThrow>>::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 7ef7f88ca110..f3558703a82a 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 <variant> // 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 <functional> #include <new> @@ -812,7 +812,7 @@ struct hash<absl::variant<T...>> } // 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 fd7e6c7fe802..b486a71e5b72 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 <iostream> #include <memory> @@ -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<Tj> or // !is_nothrow_move_constructible<Tj> 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<Tj> == false && // is_nothrow_move_constructible_v<Tj> == 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<j>(get<j>(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 b59127457148..2913775a4e59 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 <algorithm> #include <cstddef> @@ -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<std::unique_ptr<Class>> p(absl::make_unique<Class>()); absl::variant<std::unique_ptr<const Class>> 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<SpecialSwap>(v2)); EXPECT_THAT(b, VariantWith<SpecialSwap>(v1)); -#ifndef ABSL_HAVE_STD_VARIANT +#ifndef ABSL_USES_STD_VARIANT EXPECT_FALSE(absl::get<SpecialSwap>(a).special_swap); #endif @@ -2083,7 +2083,7 @@ TEST(VariantTest, Hash) { // MSVC std::hash<std::variant> does not use the index, thus produce the same // result on the same value as different alternative. -#if !(defined(_MSC_VER) && defined(ABSL_HAVE_STD_VARIANT)) +#if !(defined(_MSC_VER) && defined(ABSL_USES_STD_VARIANT)) { // same value as different alternative variant<int, int> v0(in_place_index<0>, 42); @@ -2091,7 +2091,7 @@ TEST(VariantTest, Hash) { std::hash<variant<int, int>> 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<variant<int>> 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<double> Variant; Variant v(1.0); @@ -2128,7 +2128,7 @@ TEST(VariantTest, TestConvertingSet) { ASSERT_TRUE(nullptr != absl::get_if<double>(&v)); EXPECT_DOUBLE_EQ(2, absl::get<double>(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<double, std::string> var( ConvertVariantTo<variant<double, std::string>>( variant<std::string, int>(0))); @@ -2313,7 +2313,7 @@ TEST(VariantTest, TestRvalueConversion) { variant2 = ConvertVariantTo<variant<int32_t, uint32_t>>(variant<uint32_t>(42)); ASSERT_TRUE(absl::holds_alternative<uint32_t>(variant2)); EXPECT_EQ(42, absl::get<uint32_t>(variant2)); -#endif // !ABSL_HAVE_STD_VARIANT +#endif // !ABSL_USES_STD_VARIANT variant<Convertible1, Convertible2> variant3( ConvertVariantTo<variant<Convertible1, Convertible2>>( @@ -2326,7 +2326,7 @@ TEST(VariantTest, TestRvalueConversion) { } TEST(VariantTest, TestLvalueConversion) { -#if !defined(ABSL_HAVE_STD_VARIANT) +#if !defined(ABSL_USES_STD_VARIANT) variant<std::string, int> source1 = 0; variant<double, std::string> destination( ConvertVariantTo<variant<double, std::string>>(source1)); @@ -2428,7 +2428,7 @@ TEST(VariantTest, DoesNotMoveFromLvalues) { } TEST(VariantTest, TestRvalueConversionViaConvertVariantTo) { -#if !defined(ABSL_HAVE_STD_VARIANT) +#if !defined(ABSL_USES_STD_VARIANT) variant<double, std::string> var( ConvertVariantTo<variant<double, std::string>>( variant<std::string, int>(3))); @@ -2467,7 +2467,7 @@ TEST(VariantTest, TestRvalueConversionViaConvertVariantTo) { } TEST(VariantTest, TestLvalueConversionViaConvertVariantTo) { -#if !defined(ABSL_HAVE_STD_VARIANT) +#if !defined(ABSL_USES_STD_VARIANT) variant<std::string, int> source1 = 3; variant<double, std::string> destination( ConvertVariantTo<variant<double, std::string>>(source1)); @@ -2499,7 +2499,7 @@ TEST(VariantTest, TestLvalueConversionViaConvertVariantTo) { variant<uint32_t> source6(42); variant2 = ConvertVariantTo<variant<int32_t, uint32_t>>(source6); EXPECT_THAT(absl::get_if<uint32_t>(&variant2), Pointee(42)); -#endif // !ABSL_HAVE_STD_VARIANT +#endif // !ABSL_USES_STD_VARIANT variant<Convertible2, Convertible1> source7((Convertible1())); variant<Convertible1, Convertible2> 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 eef8fb41fe8e..5a98c2c39c41 100644 --- a/absl/utility/utility.h +++ b/absl/utility/utility.h @@ -158,12 +158,12 @@ using index_sequence_for = make_index_sequence<sizeof...(Ts)>; // 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<T>); template <typename T> void in_place_type(utility_internal::InPlaceTypeTag<T>) {} -#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<I>); template <size_t I> void in_place_index(utility_internal::InPlaceIndexTag<I>) {} -#endif // ABSL_HAVE_STD_VARIANT +#endif // ABSL_USES_STD_VARIANT // Constexpr move and forward |