diff options
-rw-r--r-- | absl/base/exception_safety_testing_test.cc | 4 | ||||
-rw-r--r-- | absl/meta/type_traits.h | 23 | ||||
-rw-r--r-- | absl/meta/type_traits_test.cc | 76 | ||||
-rw-r--r-- | absl/strings/numbers.h | 2 | ||||
-rw-r--r-- | absl/strings/string_view.h | 2 | ||||
-rw-r--r-- | absl/types/internal/variant.h | 8 | ||||
-rw-r--r-- | absl/types/optional.h | 4 | ||||
-rw-r--r-- | absl/types/optional_test.cc | 29 | ||||
-rw-r--r-- | absl/types/variant_test.cc | 10 |
9 files changed, 126 insertions, 32 deletions
diff --git a/absl/base/exception_safety_testing_test.cc b/absl/base/exception_safety_testing_test.cc index 97c8d6f83189..724c0ad547ab 100644 --- a/absl/base/exception_safety_testing_test.cc +++ b/absl/base/exception_safety_testing_test.cc @@ -931,8 +931,8 @@ TEST(ThrowingValueTraitsTest, RelationalOperators) { } TEST(ThrowingAllocatorTraitsTest, Assignablility) { - EXPECT_TRUE(std::is_move_assignable<ThrowingAllocator<int>>::value); - EXPECT_TRUE(std::is_copy_assignable<ThrowingAllocator<int>>::value); + EXPECT_TRUE(absl::is_move_assignable<ThrowingAllocator<int>>::value); + EXPECT_TRUE(absl::is_copy_assignable<ThrowingAllocator<int>>::value); EXPECT_TRUE(std::is_nothrow_move_assignable<ThrowingAllocator<int>>::value); EXPECT_TRUE(std::is_nothrow_copy_assignable<ThrowingAllocator<int>>::value); } diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h index 457b890841a6..23ebd6ed0990 100644 --- a/absl/meta/type_traits.h +++ b/absl/meta/type_traits.h @@ -105,8 +105,25 @@ template <class To, template <class...> class Op, class... Args> struct is_detected_convertible : is_detected_convertible_impl<void, To, Op, Args...>::type {}; +template <typename T> +using IsCopyAssignableImpl = + decltype(std::declval<T&>() = std::declval<const T&>()); + +template <typename T> +using IsMoveAssignableImpl = decltype(std::declval<T&>() = std::declval<T&&>()); + } // namespace type_traits_internal +template <typename T> +struct is_copy_assignable : type_traits_internal::is_detected< + type_traits_internal::IsCopyAssignableImpl, T> { +}; + +template <typename T> +struct is_move_assignable : type_traits_internal::is_detected< + type_traits_internal::IsMoveAssignableImpl, T> { +}; + // void_t() // // Ignores the type of any its arguments and returns `void`. In general, this @@ -309,7 +326,7 @@ template <typename T> struct is_trivially_copy_assignable : std::integral_constant< bool, __has_trivial_assign(typename std::remove_reference<T>::type) && - std::is_copy_assignable<T>::value> { + absl::is_copy_assignable<T>::value> { #ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE private: static constexpr bool compliant = @@ -409,11 +426,11 @@ struct IsHashEnabled : absl::conjunction<std::is_default_constructible<std::hash<Key>>, std::is_copy_constructible<std::hash<Key>>, std::is_destructible<std::hash<Key>>, - std::is_copy_assignable<std::hash<Key>>, + absl::is_copy_assignable<std::hash<Key>>, IsHashable<Key>> {}; + } // namespace type_traits_internal } // namespace absl - #endif // ABSL_META_TYPE_TRAITS_H_ diff --git a/absl/meta/type_traits_test.cc b/absl/meta/type_traits_test.cc index 81b4bd323977..f51f5dedee43 100644 --- a/absl/meta/type_traits_test.cc +++ b/absl/meta/type_traits_test.cc @@ -877,4 +877,80 @@ TEST(TypeTraitsTest, TestResultOf) { EXPECT_EQ(TypeEnum::D, GetTypeExt(Wrap<TypeD>())); } +template <typename T> +bool TestCopyAssign() { + return absl::is_copy_assignable<T>::value == + std::is_copy_assignable<T>::value; +} + +TEST(TypeTraitsTest, IsCopyAssignable) { + EXPECT_TRUE(TestCopyAssign<int>()); + EXPECT_TRUE(TestCopyAssign<int&>()); + EXPECT_TRUE(TestCopyAssign<int&&>()); + + struct S {}; + EXPECT_TRUE(TestCopyAssign<S>()); + EXPECT_TRUE(TestCopyAssign<S&>()); + EXPECT_TRUE(TestCopyAssign<S&&>()); + + class C { + public: + explicit C(C* c) : c_(c) {} + ~C() { delete c_; } + + private: + C* c_; + }; + EXPECT_TRUE(TestCopyAssign<C>()); + EXPECT_TRUE(TestCopyAssign<C&>()); + EXPECT_TRUE(TestCopyAssign<C&&>()); + + // Reason for ifndef: add_lvalue_reference<T> in libc++ breaks for these cases +#ifndef _LIBCPP_VERSION + EXPECT_TRUE(TestCopyAssign<int()>()); + EXPECT_TRUE(TestCopyAssign<int(int) const>()); + EXPECT_TRUE(TestCopyAssign<int(...) volatile&>()); + EXPECT_TRUE(TestCopyAssign<int(int, ...) const volatile&&>()); +#endif // _LIBCPP_VERSION +} + +template <typename T> +bool TestMoveAssign() { + return absl::is_move_assignable<T>::value == + std::is_move_assignable<T>::value; +} + +TEST(TypeTraitsTest, IsMoveAssignable) { + EXPECT_TRUE(TestMoveAssign<int>()); + EXPECT_TRUE(TestMoveAssign<int&>()); + EXPECT_TRUE(TestMoveAssign<int&&>()); + + struct S {}; + EXPECT_TRUE(TestMoveAssign<S>()); + EXPECT_TRUE(TestMoveAssign<S&>()); + EXPECT_TRUE(TestMoveAssign<S&&>()); + + class C { + public: + explicit C(C* c) : c_(c) {} + ~C() { delete c_; } + void operator=(const C&) = delete; + void operator=(C&&) = delete; + + private: + C* c_; + }; + EXPECT_TRUE(TestMoveAssign<C>()); + EXPECT_TRUE(TestMoveAssign<C&>()); + EXPECT_TRUE(TestMoveAssign<C&&>()); + + // Reason for ifndef: add_lvalue_reference<T> in libc++ breaks for these cases +#ifndef _LIBCPP_VERSION + EXPECT_TRUE(TestMoveAssign<int()>()); + EXPECT_TRUE(TestMoveAssign<int(int) const>()); + EXPECT_TRUE(TestMoveAssign<int(...) volatile&>()); + EXPECT_TRUE(TestMoveAssign<int(int, ...) const volatile&&>()); +#endif // _LIBCPP_VERSION +} + } // namespace diff --git a/absl/strings/numbers.h b/absl/strings/numbers.h index cf3c597266cf..fbed273e0957 100644 --- a/absl/strings/numbers.h +++ b/absl/strings/numbers.h @@ -44,7 +44,7 @@ namespace absl { // Converts the given std::string into an integer value, returning `true` if // successful. The std::string must reflect a base-10 integer (optionally followed or // preceded by ASCII whitespace) whose value falls within the range of the -// integer type, +// integer type. template <typename int_type> ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view s, int_type* out); diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h index a7f9199240a2..1537a3f84283 100644 --- a/absl/strings/string_view.h +++ b/absl/strings/string_view.h @@ -141,7 +141,7 @@ namespace absl { // All empty `string_view` objects whether null or not, are equal: // // absl::string_view() == absl::string_view("", 0) -// absl::string_view(nullptr, 0) == absl:: string_view("abcdef"+6, 0) +// absl::string_view(nullptr, 0) == absl::string_view("abcdef"+6, 0) class string_view { public: using traits_type = std::char_traits<char>; diff --git a/absl/types/internal/variant.h b/absl/types/internal/variant.h index 7708e67cb14f..28ae1a5a7e3c 100644 --- a/absl/types/internal/variant.h +++ b/absl/types/internal/variant.h @@ -1227,23 +1227,23 @@ using VariantCopyBase = absl::conditional_t< // Base that is dependent on whether or not the move-assign can be trivial. template <class... T> using VariantMoveAssignBase = absl::conditional_t< - absl::disjunction<absl::conjunction<std::is_move_assignable<Union<T...>>, + absl::disjunction<absl::conjunction<absl::is_move_assignable<Union<T...>>, std::is_move_constructible<Union<T...>>, std::is_destructible<Union<T...>>>, absl::negation<absl::conjunction< std::is_move_constructible<T>..., - std::is_move_assignable<T>...>>>::value, + absl::is_move_assignable<T>...>>>::value, VariantCopyBase<T...>, VariantMoveAssignBaseNontrivial<T...>>; // Base that is dependent on whether or not the copy-assign can be trivial. template <class... T> using VariantCopyAssignBase = absl::conditional_t< - absl::disjunction<absl::conjunction<std::is_copy_assignable<Union<T...>>, + absl::disjunction<absl::conjunction<absl::is_copy_assignable<Union<T...>>, std::is_copy_constructible<Union<T...>>, std::is_destructible<Union<T...>>>, absl::negation<absl::conjunction< std::is_copy_constructible<T>..., - std::is_copy_assignable<T>...>>>::value, + absl::is_copy_assignable<T>...>>>::value, VariantMoveAssignBase<T...>, VariantCopyAssignBaseNontrivial<T...>>; template <class... T> diff --git a/absl/types/optional.h b/absl/types/optional.h index c837cddeef48..79475e3ea3b3 100644 --- a/absl/types/optional.h +++ b/absl/types/optional.h @@ -411,10 +411,10 @@ constexpr copy_traits get_ctor_copy_traits() { template <typename T> constexpr copy_traits get_assign_copy_traits() { - return std::is_copy_assignable<T>::value && + return absl::is_copy_assignable<T>::value && std::is_copy_constructible<T>::value ? copy_traits::copyable - : std::is_move_assignable<T>::value && + : absl::is_move_assignable<T>::value && std::is_move_constructible<T>::value ? copy_traits::movable : copy_traits::non_movable; diff --git a/absl/types/optional_test.cc b/absl/types/optional_test.cc index 179bfd66d2fe..d90db9f821b5 100644 --- a/absl/types/optional_test.cc +++ b/absl/types/optional_test.cc @@ -607,11 +607,12 @@ TEST(optionalTest, CopyAssignment) { opt2_to_empty = empty; EXPECT_FALSE(opt2_to_empty); - EXPECT_FALSE(std::is_copy_assignable<absl::optional<const int>>::value); - EXPECT_TRUE(std::is_copy_assignable<absl::optional<Copyable>>::value); - EXPECT_FALSE(std::is_copy_assignable<absl::optional<MoveableThrow>>::value); - EXPECT_FALSE(std::is_copy_assignable<absl::optional<MoveableNoThrow>>::value); - EXPECT_FALSE(std::is_copy_assignable<absl::optional<NonMovable>>::value); + EXPECT_FALSE(absl::is_copy_assignable<absl::optional<const int>>::value); + EXPECT_TRUE(absl::is_copy_assignable<absl::optional<Copyable>>::value); + EXPECT_FALSE(absl::is_copy_assignable<absl::optional<MoveableThrow>>::value); + EXPECT_FALSE( + absl::is_copy_assignable<absl::optional<MoveableNoThrow>>::value); + EXPECT_FALSE(absl::is_copy_assignable<absl::optional<NonMovable>>::value); EXPECT_TRUE(absl::is_trivially_copy_assignable<int>::value); EXPECT_TRUE(absl::is_trivially_copy_assignable<volatile int>::value); @@ -625,9 +626,9 @@ TEST(optionalTest, CopyAssignment) { }; EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial>::value); - EXPECT_FALSE(std::is_copy_assignable<const Trivial>::value); - EXPECT_FALSE(std::is_copy_assignable<volatile Trivial>::value); - EXPECT_TRUE(std::is_copy_assignable<NonTrivial>::value); + EXPECT_FALSE(absl::is_copy_assignable<const Trivial>::value); + EXPECT_FALSE(absl::is_copy_assignable<volatile Trivial>::value); + EXPECT_TRUE(absl::is_copy_assignable<NonTrivial>::value); EXPECT_FALSE(absl::is_trivially_copy_assignable<NonTrivial>::value); // std::optional doesn't support volatile nontrivial types. @@ -695,11 +696,11 @@ TEST(optionalTest, MoveAssignment) { EXPECT_EQ(1, listener.volatile_move_assign); } #endif // ABSL_HAVE_STD_OPTIONAL - EXPECT_FALSE(std::is_move_assignable<absl::optional<const int>>::value); - EXPECT_TRUE(std::is_move_assignable<absl::optional<Copyable>>::value); - EXPECT_TRUE(std::is_move_assignable<absl::optional<MoveableThrow>>::value); - EXPECT_TRUE(std::is_move_assignable<absl::optional<MoveableNoThrow>>::value); - EXPECT_FALSE(std::is_move_assignable<absl::optional<NonMovable>>::value); + 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); + EXPECT_TRUE(absl::is_move_assignable<absl::optional<MoveableNoThrow>>::value); + EXPECT_FALSE(absl::is_move_assignable<absl::optional<NonMovable>>::value); EXPECT_FALSE( std::is_nothrow_move_assignable<absl::optional<MoveableThrow>>::value); @@ -1619,7 +1620,7 @@ TEST(optionalTest, AssignmentConstraints) { EXPECT_TRUE( (std::is_assignable<absl::optional<AnyLike>&, const AnyLike&>::value)); EXPECT_TRUE(std::is_move_assignable<absl::optional<AnyLike>>::value); - EXPECT_TRUE(std::is_copy_assignable<absl::optional<AnyLike>>::value); + EXPECT_TRUE(absl::is_copy_assignable<absl::optional<AnyLike>>::value); } } // namespace diff --git a/absl/types/variant_test.cc b/absl/types/variant_test.cc index 262bd9446c18..bfb8bd7a0223 100644 --- a/absl/types/variant_test.cc +++ b/absl/types/variant_test.cc @@ -403,7 +403,7 @@ struct is_trivially_move_constructible template <class T> struct is_trivially_move_assignable - : std::is_move_assignable<SingleUnion<T>>::type {}; + : absl::is_move_assignable<SingleUnion<T>>::type {}; TEST(VariantTest, NothrowMoveConstructible) { // Verify that variant is nothrow move constructible iff its template @@ -2439,14 +2439,14 @@ TEST(VariantTest, TestMoveConversionViaConvertVariantTo) { TEST(VariantTest, TestCopyAndMoveTypeTraits) { EXPECT_TRUE(std::is_copy_constructible<variant<std::string>>::value); - EXPECT_TRUE(std::is_copy_assignable<variant<std::string>>::value); + EXPECT_TRUE(absl::is_copy_assignable<variant<std::string>>::value); EXPECT_TRUE(std::is_move_constructible<variant<std::string>>::value); - EXPECT_TRUE(std::is_move_assignable<variant<std::string>>::value); + EXPECT_TRUE(absl::is_move_assignable<variant<std::string>>::value); EXPECT_TRUE(std::is_move_constructible<variant<std::unique_ptr<int>>>::value); - EXPECT_TRUE(std::is_move_assignable<variant<std::unique_ptr<int>>>::value); + EXPECT_TRUE(absl::is_move_assignable<variant<std::unique_ptr<int>>>::value); EXPECT_FALSE( std::is_copy_constructible<variant<std::unique_ptr<int>>>::value); - EXPECT_FALSE(std::is_copy_assignable<variant<std::unique_ptr<int>>>::value); + EXPECT_FALSE(absl::is_copy_assignable<variant<std::unique_ptr<int>>>::value); EXPECT_FALSE( absl::is_trivially_copy_constructible<variant<std::string>>::value); |