// 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_ #include namespace cppgc { class Visitor; namespace internal { // 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 {}; template class U> struct IsSubclassOfTemplate { private: template static std::true_type SubclassCheck(U*); static std::false_type SubclassCheck(...); public: static constexpr bool value = decltype(SubclassCheck(std::declval()))::value; }; // 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 IsGarbageCollectedMixinType : std::false_type { static_assert(sizeof(T), "T must be fully defined"); }; template struct IsGarbageCollectedMixinType< T, void_t::IsGarbageCollectedMixinTypeMarker>> : std::true_type { static_assert(sizeof(T), "T must be fully defined"); }; template struct IsGarbageCollectedType : IsGarbageCollectedMixinType { static_assert(sizeof(T), "T must be fully defined"); }; template struct IsGarbageCollectedType< T, void_t::IsGarbageCollectedTypeMarker>> : std::true_type { static_assert(sizeof(T), "T must be fully defined"); }; template constexpr bool IsGarbageCollectedTypeV = internal::IsGarbageCollectedType::value; template constexpr bool IsGarbageCollectedMixinTypeV = internal::IsGarbageCollectedMixinType::value; } // namespace internal template constexpr bool IsWeakV = internal::IsWeak::value; } // namespace cppgc #endif // INCLUDE_CPPGC_TYPE_TRAITS_H_