diff options
author | Abseil Team <absl-team@google.com> | 2019-08-19T17·27-0700 |
---|---|---|
committer | Xiaoyi Zhang <zhangxy@google.com> | 2019-08-19T19·34-0400 |
commit | 0e7afdcbd24c7e5b7cab4e0217d8886f1525b520 (patch) | |
tree | 4f01b59581a9ecfd7e3bb833d609ab53fbe50e19 /absl/types | |
parent | 9a41ffdd3a0ccbcdd29c4e3886b28e06f2cd9c66 (diff) |
Export of internal Abseil changes
-- 62058c9c008e23c787f35c1a5fe05851046a71f1 by Abseil Team <absl-team@google.com>: Fix some strange usage of INSTANTIATE_TEST_SUITE_P PiperOrigin-RevId: 264185105 -- 4400d84027d86415a2f9b81996ff22e7fd7aa30f by Derek Mauro <dmauro@google.com>: Disable testing std::string_view from nullptr on GCC >= GCC9. PiperOrigin-RevId: 264150587 -- 656d5a742ba48d025589709fad33ddae4b02c620 by Matt Calabrese <calabrese@google.com>: Fix `absl::any_cast` such that it properly works with qualifications. PiperOrigin-RevId: 263843429 -- 6ec89214a4ef2170bf069623a56ffd22863b748d by Abseil Team <absl-team@google.com>: Use macros to enable inline constexpr variables in compare.h when the compiler supports the feature. PiperOrigin-RevId: 263790677 -- a5171e0897195a0367fc08abce9504f813d027ff by Derek Mauro <dmauro@google.com>: Add the Apache License to files that are missing it. PiperOrigin-RevId: 263774164 -- 19e09a7ce8a0aac0a7d534e1799e4d73b63a1bb5 by Abseil Team <absl-team@google.com>: Update iter.position when moving up the tree in rebalance_after_delete. This field isn't read after the first iteration in rebalance_after_delete, and I think it's not a correctness issue, but it is read in try_merge_or_rebalance and potentially affects rebalancing decisions so it can affect performance. There's also an extremely unlikely potential for undefined behavior due to signed integer overflow since this field is only ever incremented in try_merge_or_rebalance (and position is an int). Basically though, I just don't think it makes sense to have this invalid iterator floating around here. PiperOrigin-RevId: 263770305 GitOrigin-RevId: 62058c9c008e23c787f35c1a5fe05851046a71f1 Change-Id: I1e2fb7cbfac7507dddedd181414ee35a5778f8f5
Diffstat (limited to 'absl/types')
-rw-r--r-- | absl/types/any.h | 12 | ||||
-rw-r--r-- | absl/types/compare.h | 150 | ||||
-rw-r--r-- | absl/types/compare_test.cc | 26 |
3 files changed, 133 insertions, 55 deletions
diff --git a/absl/types/any.h b/absl/types/any.h index f3a32812662f..d2e2533f05bc 100644 --- a/absl/types/any.h +++ b/absl/types/any.h @@ -515,18 +515,22 @@ ValueType any_cast(any&& operand) { // Description at the declaration site (top of file). template <typename T> const T* any_cast(const any* operand) noexcept { - return operand && operand->GetObjTypeId() == any::IdForType<T>() + using U = + typename std::remove_cv<typename std::remove_reference<T>::type>::type; + return operand && operand->GetObjTypeId() == any::IdForType<U>() ? std::addressof( - static_cast<const any::Obj<T>*>(operand->obj_.get())->value) + static_cast<const any::Obj<U>*>(operand->obj_.get())->value) : nullptr; } // Description at the declaration site (top of file). template <typename T> T* any_cast(any* operand) noexcept { - return operand && operand->GetObjTypeId() == any::IdForType<T>() + using U = + typename std::remove_cv<typename std::remove_reference<T>::type>::type; + return operand && operand->GetObjTypeId() == any::IdForType<U>() ? std::addressof( - static_cast<any::Obj<T>*>(operand->obj_.get())->value) + static_cast<any::Obj<U>*>(operand->obj_.get())->value) : nullptr; } diff --git a/absl/types/compare.h b/absl/types/compare.h index 50361d623025..a213e0b0b682 100644 --- a/absl/types/compare.h +++ b/absl/types/compare.h @@ -79,79 +79,72 @@ enum class ord : value_type { less = -1, greater = 1 }; enum class ncmp : value_type { unordered = -127 }; +// Define macros to allow for creation or emulation of C++17 inline variables +// based on whether the feature is supported. Note: we can't use +// ABSL_INTERNAL_INLINE_CONSTEXPR here because the variables here are of +// incomplete types so they need to be defined after the types are complete. +#ifdef __cpp_inline_variables + +#define ABSL_COMPARE_INLINE_BASECLASS_DECL(name) + +#define ABSL_COMPARE_INLINE_SUBCLASS_DECL(type, name) \ + static const type name + +#define ABSL_COMPARE_INLINE_INIT(type, name, init) \ + inline constexpr type type::name(init) + +#else // __cpp_inline_variables + +#define ABSL_COMPARE_INLINE_BASECLASS_DECL(name) \ + ABSL_CONST_INIT static const T name + +#define ABSL_COMPARE_INLINE_SUBCLASS_DECL(type, name) + +#define ABSL_COMPARE_INLINE_INIT(type, name, init) \ + template <typename T> \ + const T compare_internal::type##_base<T>::name(init) + +#endif // __cpp_inline_variables + // These template base classes allow for defining the values of the constants // in the header file (for performance) without using inline variables (which // aren't available in C++11). template <typename T> struct weak_equality_base { - ABSL_CONST_INIT static const T equivalent; - ABSL_CONST_INIT static const T nonequivalent; + ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent); + ABSL_COMPARE_INLINE_BASECLASS_DECL(nonequivalent); }; -template <typename T> -const T weak_equality_base<T>::equivalent(eq::equivalent); -template <typename T> -const T weak_equality_base<T>::nonequivalent(eq::nonequivalent); template <typename T> struct strong_equality_base { - ABSL_CONST_INIT static const T equal; - ABSL_CONST_INIT static const T nonequal; - ABSL_CONST_INIT static const T equivalent; - ABSL_CONST_INIT static const T nonequivalent; + ABSL_COMPARE_INLINE_BASECLASS_DECL(equal); + ABSL_COMPARE_INLINE_BASECLASS_DECL(nonequal); + ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent); + ABSL_COMPARE_INLINE_BASECLASS_DECL(nonequivalent); }; -template <typename T> -const T strong_equality_base<T>::equal(eq::equal); -template <typename T> -const T strong_equality_base<T>::nonequal(eq::nonequal); -template <typename T> -const T strong_equality_base<T>::equivalent(eq::equivalent); -template <typename T> -const T strong_equality_base<T>::nonequivalent(eq::nonequivalent); template <typename T> struct partial_ordering_base { - ABSL_CONST_INIT static const T less; - ABSL_CONST_INIT static const T equivalent; - ABSL_CONST_INIT static const T greater; - ABSL_CONST_INIT static const T unordered; + ABSL_COMPARE_INLINE_BASECLASS_DECL(less); + ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent); + ABSL_COMPARE_INLINE_BASECLASS_DECL(greater); + ABSL_COMPARE_INLINE_BASECLASS_DECL(unordered); }; -template <typename T> -const T partial_ordering_base<T>::less(ord::less); -template <typename T> -const T partial_ordering_base<T>::equivalent(eq::equivalent); -template <typename T> -const T partial_ordering_base<T>::greater(ord::greater); -template <typename T> -const T partial_ordering_base<T>::unordered(ncmp::unordered); template <typename T> struct weak_ordering_base { - ABSL_CONST_INIT static const T less; - ABSL_CONST_INIT static const T equivalent; - ABSL_CONST_INIT static const T greater; + ABSL_COMPARE_INLINE_BASECLASS_DECL(less); + ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent); + ABSL_COMPARE_INLINE_BASECLASS_DECL(greater); }; -template <typename T> -const T weak_ordering_base<T>::less(ord::less); -template <typename T> -const T weak_ordering_base<T>::equivalent(eq::equivalent); -template <typename T> -const T weak_ordering_base<T>::greater(ord::greater); template <typename T> struct strong_ordering_base { - ABSL_CONST_INIT static const T less; - ABSL_CONST_INIT static const T equal; - ABSL_CONST_INIT static const T equivalent; - ABSL_CONST_INIT static const T greater; + ABSL_COMPARE_INLINE_BASECLASS_DECL(less); + ABSL_COMPARE_INLINE_BASECLASS_DECL(equal); + ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent); + ABSL_COMPARE_INLINE_BASECLASS_DECL(greater); }; -template <typename T> -const T strong_ordering_base<T>::less(ord::less); -template <typename T> -const T strong_ordering_base<T>::equal(eq::equal); -template <typename T> -const T strong_ordering_base<T>::equivalent(eq::equivalent); -template <typename T> -const T strong_ordering_base<T>::greater(ord::greater); } // namespace compare_internal @@ -162,6 +155,9 @@ class weak_equality friend struct compare_internal::weak_equality_base<weak_equality>; public: + ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_equality, equivalent); + ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_equality, nonequivalent); + // Comparisons friend constexpr bool operator==( weak_equality v, compare_internal::OnlyLiteralZero<>) noexcept { @@ -183,6 +179,10 @@ class weak_equality private: compare_internal::value_type value_; }; +ABSL_COMPARE_INLINE_INIT(weak_equality, equivalent, + compare_internal::eq::equivalent); +ABSL_COMPARE_INLINE_INIT(weak_equality, nonequivalent, + compare_internal::eq::nonequivalent); class strong_equality : public compare_internal::strong_equality_base<strong_equality> { @@ -191,6 +191,11 @@ class strong_equality friend struct compare_internal::strong_equality_base<strong_equality>; public: + ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_equality, equal); + ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_equality, nonequal); + ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_equality, equivalent); + ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_equality, nonequivalent); + // Conversion constexpr operator weak_equality() const noexcept { // NOLINT return value_ == 0 ? weak_equality::equivalent @@ -217,6 +222,13 @@ class strong_equality private: compare_internal::value_type value_; }; +ABSL_COMPARE_INLINE_INIT(strong_equality, equal, compare_internal::eq::equal); +ABSL_COMPARE_INLINE_INIT(strong_equality, nonequal, + compare_internal::eq::nonequal); +ABSL_COMPARE_INLINE_INIT(strong_equality, equivalent, + compare_internal::eq::equivalent); +ABSL_COMPARE_INLINE_INIT(strong_equality, nonequivalent, + compare_internal::eq::nonequivalent); class partial_ordering : public compare_internal::partial_ordering_base<partial_ordering> { @@ -234,6 +246,11 @@ class partial_ordering } public: + ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, less); + ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, equivalent); + ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, greater); + ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, unordered); + // Conversion constexpr operator weak_equality() const noexcept { // NOLINT return value_ == 0 ? weak_equality::equivalent @@ -292,6 +309,13 @@ class partial_ordering private: compare_internal::value_type value_; }; +ABSL_COMPARE_INLINE_INIT(partial_ordering, less, compare_internal::ord::less); +ABSL_COMPARE_INLINE_INIT(partial_ordering, equivalent, + compare_internal::eq::equivalent); +ABSL_COMPARE_INLINE_INIT(partial_ordering, greater, + compare_internal::ord::greater); +ABSL_COMPARE_INLINE_INIT(partial_ordering, unordered, + compare_internal::ncmp::unordered); class weak_ordering : public compare_internal::weak_ordering_base<weak_ordering> { @@ -302,6 +326,10 @@ class weak_ordering friend struct compare_internal::weak_ordering_base<weak_ordering>; public: + ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, less); + ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, equivalent); + ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, greater); + // Conversions constexpr operator weak_equality() const noexcept { // NOLINT return value_ == 0 ? weak_equality::equivalent @@ -365,6 +393,11 @@ class weak_ordering private: compare_internal::value_type value_; }; +ABSL_COMPARE_INLINE_INIT(weak_ordering, less, compare_internal::ord::less); +ABSL_COMPARE_INLINE_INIT(weak_ordering, equivalent, + compare_internal::eq::equivalent); +ABSL_COMPARE_INLINE_INIT(weak_ordering, greater, + compare_internal::ord::greater); class strong_ordering : public compare_internal::strong_ordering_base<strong_ordering> { @@ -375,6 +408,11 @@ class strong_ordering friend struct compare_internal::strong_ordering_base<strong_ordering>; public: + ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, less); + ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, equal); + ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, equivalent); + ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, greater); + // Conversions constexpr operator weak_equality() const noexcept { // NOLINT return value_ == 0 ? weak_equality::equivalent @@ -446,6 +484,16 @@ class strong_ordering private: compare_internal::value_type value_; }; +ABSL_COMPARE_INLINE_INIT(strong_ordering, less, compare_internal::ord::less); +ABSL_COMPARE_INLINE_INIT(strong_ordering, equal, compare_internal::eq::equal); +ABSL_COMPARE_INLINE_INIT(strong_ordering, equivalent, + compare_internal::eq::equivalent); +ABSL_COMPARE_INLINE_INIT(strong_ordering, greater, + compare_internal::ord::greater); + +#undef ABSL_COMPARE_INLINE_BASECLASS_DECL +#undef ABSL_COMPARE_INLINE_SUBCLASS_DECL +#undef ABSL_COMPARE_INLINE_INIT namespace compare_internal { // We also provide these comparator adapter functions for internal absl use. diff --git a/absl/types/compare_test.cc b/absl/types/compare_test.cc index 3a8554219274..ee396fc54d7c 100644 --- a/absl/types/compare_test.cc +++ b/absl/types/compare_test.cc @@ -307,5 +307,31 @@ TEST(DoThreeWayComparison, SanityTest) { absl::compare_internal::do_three_way_comparison(weak, 10, 5) > 0)); } +#ifdef __cpp_inline_variables +TEST(Compare, StaticAsserts) { + static_assert(weak_equality::equivalent == 0, ""); + static_assert(weak_equality::nonequivalent != 0, ""); + + static_assert(strong_equality::equal == 0, ""); + static_assert(strong_equality::nonequal != 0, ""); + static_assert(strong_equality::equivalent == 0, ""); + static_assert(strong_equality::nonequivalent != 0, ""); + + static_assert(partial_ordering::less < 0, ""); + static_assert(partial_ordering::equivalent == 0, ""); + static_assert(partial_ordering::greater > 0, ""); + static_assert(partial_ordering::unordered != 0, ""); + + static_assert(weak_ordering::less < 0, ""); + static_assert(weak_ordering::equivalent == 0, ""); + static_assert(weak_ordering::greater > 0, ""); + + static_assert(strong_ordering::less < 0, ""); + static_assert(strong_ordering::equal == 0, ""); + static_assert(strong_ordering::equivalent == 0, ""); + static_assert(strong_ordering::greater > 0, ""); +} +#endif // __cpp_inline_variables + } // namespace } // namespace absl |