Export of internal Abseil changes.
-- c1f3a243ff3713917eaf0255c86ddd1b40461ba9 by Abseil Team <absl-team@google.com>: Remove stray space. PiperOrigin-RevId: 207753171 -- 4abe43b174f7fafa390d2f6eb96f31977a38fc69 by Shaindel Schwartz <shaindel@google.com>: Typo fix. PiperOrigin-RevId: 207572868 -- e7757b409256b025cadba20a84a93cb9dc4319e1 by Abseil Team <absl-team@google.com>: Adds backported is_(copy|move)_assignable<T> PiperOrigin-RevId: 207572180 GitOrigin-RevId: c1f3a243ff3713917eaf0255c86ddd1b40461ba9 Change-Id: I1202715e5092b54d5967017728044715d6eb2ec0
This commit is contained in:
parent
bea85b5273
commit
083d04dd4a
9 changed files with 126 additions and 32 deletions
|
|
@ -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_
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue