v8/v8
0

cppgc: Fix trait and add new helper traits

- Fix trait to be usable with non-decayed types. Users generally want to
  check for Member on const qualified types and references.
- Add IsMemberOrWeakMemberTypeV: This is a commonly used trait to check
  for types that require a write barrier.
- Add IsAnyMemberTypeV: This is a commonly used trait to check for
  whether types should be accessed like Member.

Bug: chromium:1492410
Change-Id: I358a2aa02b1bfce8ed03652a7afe5c8ef7bd35c8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4967413
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Anton Bikineev <bikineev@chromium.org>
Cr-Commit-Position: refs/heads/main@{#90537}
This commit is contained in:
Michael Lippautz
2023-10-23 17:27:37 +02:00
committed by V8 LUCI CQ
parent 202e60cacc
commit 2ee5eeb3cc
2 changed files with 49 additions and 4 deletions
include/cppgc
test/unittests/heap/cppgc

@ -128,13 +128,13 @@ struct IsSubclassOfBasicMemberTemplate {
private:
template <typename T, typename CheckingPolicy, typename StorageType>
static std::true_type SubclassCheck(
BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
StorageType>*);
const BasicMember<T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy,
StorageType>*);
static std::false_type SubclassCheck(...);
public:
static constexpr bool value =
decltype(SubclassCheck(std::declval<BasicMemberCandidate*>()))::value;
static constexpr bool value = decltype(SubclassCheck(
std::declval<std::decay_t<BasicMemberCandidate>*>()))::value;
};
template <typename T,
@ -180,6 +180,14 @@ constexpr bool IsStrictlyBaseOfV =
std::is_base_of_v<std::decay_t<B>, std::decay_t<D>> &&
!IsDecayedSameV<B, D>;
template <typename T>
constexpr bool IsAnyMemberTypeV = false;
template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
typename CheckingPolicy, typename StorageType>
constexpr bool IsAnyMemberTypeV<internal::BasicMember<
T, WeaknessTag, WriteBarrierPolicy, CheckingPolicy, StorageType>> = true;
} // namespace internal
/**
@ -245,6 +253,19 @@ constexpr bool IsWeakV = internal::IsWeak<T>::value;
template <typename T>
constexpr bool IsCompleteV = internal::IsComplete<T>::value;
/**
* Value is true for member types `Member<T>` and `WeakMember<T>`.
*/
template <typename T>
constexpr bool IsMemberOrWeakMemberTypeV =
IsMemberTypeV<T> || IsWeakMemberTypeV<T>;
/**
* Value is true for any member type.
*/
template <typename T>
constexpr bool IsAnyMemberTypeV = internal::IsAnyMemberTypeV<std::decay_t<T>>;
} // namespace cppgc
#endif // INCLUDE_CPPGC_TYPE_TRAITS_H_

@ -10,6 +10,7 @@
#include "include/cppgc/allocation.h"
#include "include/cppgc/garbage-collected.h"
#include "include/cppgc/internal/member-storage.h"
#include "include/cppgc/internal/pointer-policies.h"
#include "include/cppgc/persistent.h"
#include "include/cppgc/sentinel-pointer.h"
#include "include/cppgc/type-traits.h"
@ -39,6 +40,10 @@ static_assert(!IsWeakV<Member<GCed>>, "Member is always strong.");
static_assert(IsWeakV<WeakMember<GCed>>, "WeakMember is always weak.");
static_assert(IsMemberTypeV<Member<GCed>>, "Member must be Member.");
static_assert(IsMemberTypeV<const Member<GCed>>,
"const Member must be Member.");
static_assert(IsMemberTypeV<const Member<GCed>&>,
"const Member ref must be Member.");
static_assert(!IsMemberTypeV<WeakMember<GCed>>,
"WeakMember must not be Member.");
static_assert(!IsMemberTypeV<UntracedMember<GCed>>,
@ -58,6 +63,25 @@ static_assert(!IsUntracedMemberTypeV<WeakMember<GCed>>,
static_assert(IsUntracedMemberTypeV<UntracedMember<GCed>>,
"UntracedMember must be UntracedMember.");
static_assert(!IsUntracedMemberTypeV<int>, "int must not be UntracedMember.");
static_assert(IsMemberOrWeakMemberTypeV<Member<GCed>>,
"Member must be Member.");
static_assert(IsMemberOrWeakMemberTypeV<WeakMember<GCed>>,
"WeakMember must be WeakMember.");
static_assert(!IsMemberOrWeakMemberTypeV<UntracedMember<GCed>>,
"UntracedMember is neither Member nor WeakMember.");
static_assert(!IsMemberOrWeakMemberTypeV<int>,
"int is neither Member nor WeakMember.");
static_assert(IsAnyMemberTypeV<Member<GCed>>, "Member must be a member type.");
static_assert(IsAnyMemberTypeV<WeakMember<GCed>>,
"WeakMember must be a member type.");
static_assert(IsAnyMemberTypeV<UntracedMember<GCed>>,
"UntracedMember must be a member type.");
static_assert(!IsAnyMemberTypeV<int>, "int must not be a member type.");
static_assert(
IsAnyMemberTypeV<
internal::BasicMember<GCed, class SomeTag, NoWriteBarrierPolicy,
DefaultMemberCheckingPolicy, RawPointer>>,
"Any custom member must be a member type.");
struct CustomWriteBarrierPolicy {
static size_t InitializingWriteBarriersTriggered;