| | |
| | |
| | |
| |
|
| | #ifndef INCLUDE_CPPGC_TRACE_TRAIT_H_ |
| | #define INCLUDE_CPPGC_TRACE_TRAIT_H_ |
| |
|
| | #include <type_traits> |
| | #include "cppgc/type-traits.h" |
| |
|
| | namespace cppgc { |
| |
|
| | class Visitor; |
| |
|
| | namespace internal { |
| |
|
| | template <typename T, |
| | bool = |
| | IsGarbageCollectedMixinTypeV<typename std::remove_const<T>::type>> |
| | struct TraceTraitImpl; |
| |
|
| | } |
| |
|
| | using TraceCallback = void (*)(Visitor*, const void*); |
| |
|
| | |
| | struct TraceDescriptor { |
| | |
| | const void* base_object_payload; |
| | |
| | TraceCallback callback; |
| | }; |
| |
|
| | template <typename T> |
| | struct TraceTrait { |
| | static_assert(internal::IsTraceableV<T>, "T must have a Trace() method"); |
| |
|
| | static TraceDescriptor GetTraceDescriptor(const void* self) { |
| | return internal::TraceTraitImpl<T>::GetTraceDescriptor( |
| | static_cast<const T*>(self)); |
| | } |
| |
|
| | static void Trace(Visitor* visitor, const void* self) { |
| | static_cast<const T*>(self)->Trace(visitor); |
| | } |
| | }; |
| |
|
| | namespace internal { |
| |
|
| | template <typename T> |
| | struct TraceTraitImpl<T, false> { |
| | static TraceDescriptor GetTraceDescriptor(const void* self) { |
| | return {self, TraceTrait<T>::Trace}; |
| | } |
| | }; |
| |
|
| | template <typename T> |
| | struct TraceTraitImpl<T, true> { |
| | static TraceDescriptor GetTraceDescriptor(const void* self) { |
| | return static_cast<const T*>(self)->GetTraceDescriptor(); |
| | } |
| | }; |
| |
|
| | } |
| | } |
| |
|
| | #endif |
| |
|