// Copyright 2020 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef INCLUDE_CPPGC_TYPE_TRAITS_H_ #define INCLUDE_CPPGC_TYPE_TRAITS_H_ // This file should stay with minimal dependencies to allow embedder to check // against Oilpan types without including any other parts. #include #include namespace cppgc { class Visitor; namespace internal { template class BasicMember; struct DijkstraWriteBarrierPolicy; struct NoWriteBarrierPolicy; class StrongMemberTag; class UntracedMemberTag; class WeakMemberTag; // Pre-C++17 custom implementation of std::void_t. template struct make_void { typedef void type; }; template using void_t = typename make_void::type; // Not supposed to be specialized by the user. template struct IsWeak : std::false_type {}; // IsTraceMethodConst is used to verify that all Trace methods are marked as // const. It is equivalent to IsTraceable but for a non-const object. template struct IsTraceMethodConst : std::false_type {}; template struct IsTraceMethodConst().Trace( std::declval()))>> : std::true_type { }; template struct IsTraceable : std::false_type { static_assert(sizeof(T), "T must be fully defined"); }; template struct IsTraceable< T, void_t().Trace(std::declval()))>> : std::true_type { // All Trace methods should be marked as const. If an object of type // 'T' is traceable then any object of type 'const T' should also // be traceable. static_assert(IsTraceMethodConst(), "Trace methods should be marked as const."); }; template constexpr bool IsTraceableV = IsTraceable::value; template struct HasGarbageCollectedMixinTypeMarker : std::false_type { static_assert(sizeof(T), "T must be fully defined"); }; template struct HasGarbageCollectedMixinTypeMarker< T, void_t::IsGarbageCollectedMixinTypeMarker>> : std::true_type { static_assert(sizeof(T), "T must be fully defined"); }; template struct HasGarbageCollectedTypeMarker : std::false_type { static_assert(sizeof(T), "T must be fully defined"); }; template struct HasGarbageCollectedTypeMarker< T, void_t::IsGarbageCollectedTypeMarker>> : std::true_type { static_assert(sizeof(T), "T must be fully defined"); }; template ::value, bool = HasGarbageCollectedMixinTypeMarker::value> struct IsGarbageCollectedMixinType : std::false_type { static_assert(sizeof(T), "T must be fully defined"); }; template struct IsGarbageCollectedMixinType : std::true_type { static_assert(sizeof(T), "T must be fully defined"); }; template ::value> struct IsGarbageCollectedType : std::false_type { static_assert(sizeof(T), "T must be fully defined"); }; template struct IsGarbageCollectedType : std::true_type { static_assert(sizeof(T), "T must be fully defined"); }; template struct IsGarbageCollectedOrMixinType : std::integral_constant::value || IsGarbageCollectedMixinType::value> { static_assert(sizeof(T), "T must be fully defined"); }; template ::value && HasGarbageCollectedMixinTypeMarker::value)> struct IsGarbageCollectedWithMixinType : std::false_type { static_assert(sizeof(T), "T must be fully defined"); }; template struct IsGarbageCollectedWithMixinType : std::true_type { static_assert(sizeof(T), "T must be fully defined"); }; template struct IsSubclassOfBasicMemberTemplate { private: template static std::true_type SubclassCheck( BasicMember*); static std::false_type SubclassCheck(...); public: static constexpr bool value = decltype(SubclassCheck(std::declval()))::value; }; template ::value> struct IsMemberType : std::false_type {}; template struct IsMemberType : std::true_type {}; template ::value> struct IsWeakMemberType : std::false_type {}; template struct IsWeakMemberType : std::true_type {}; template ::value> struct IsUntracedMemberType : std::false_type {}; template struct IsUntracedMemberType : std::true_type {}; template struct IsComplete { private: template static std::true_type IsSizeOfKnown(U*); static std::false_type IsSizeOfKnown(...); public: static constexpr bool value = decltype(IsSizeOfKnown(std::declval()))::value; }; } // namespace internal /** * Value is true for types that inherit from `GarbageCollectedMixin` but not * `GarbageCollected` (i.e., they are free mixins), and false otherwise. */ template constexpr bool IsGarbageCollectedMixinTypeV = internal::IsGarbageCollectedMixinType::value; /** * Value is true for types that inherit from `GarbageCollected`, and false * otherwise. */ template constexpr bool IsGarbageCollectedTypeV = internal::IsGarbageCollectedType::value; /** * Value is true for types that inherit from either `GarbageCollected` or * `GarbageCollectedMixin`, and false otherwise. */ template constexpr bool IsGarbageCollectedOrMixinTypeV = internal::IsGarbageCollectedOrMixinType::value; /** * Value is true for types that inherit from `GarbageCollected` and * `GarbageCollectedMixin`, and false otherwise. */ template constexpr bool IsGarbageCollectedWithMixinTypeV = internal::IsGarbageCollectedWithMixinType::value; /** * Value is true for types of type `Member`, and false otherwise. */ template constexpr bool IsMemberTypeV = internal::IsMemberType::value; /** * Value is true for types of type `UntracedMember`, and false otherwise. */ template constexpr bool IsUntracedMemberTypeV = internal::IsUntracedMemberType::value; /** * Value is true for types of type `WeakMember`, and false otherwise. */ template constexpr bool IsWeakMemberTypeV = internal::IsWeakMemberType::value; /** * Value is true for types that are considered weak references, and false * otherwise. */ template constexpr bool IsWeakV = internal::IsWeak::value; /** * Value is true for types that are complete, and false otherwise. */ template constexpr bool IsCompleteV = internal::IsComplete::value; } // namespace cppgc #endif // INCLUDE_CPPGC_TYPE_TRAITS_H_