1 /* 2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef FOUNDATION_ACE_FRAMEWORKS_BASE_MEMORY_TYPE_INFO_BASE_H 17 #define FOUNDATION_ACE_FRAMEWORKS_BASE_MEMORY_TYPE_INFO_BASE_H 18 19 #include <string> 20 21 #include "base/memory/memory_monitor_def.h" 22 23 // Generate 'TypeInfo' for each classes. 24 // And using hash code of its name for 'TypeId'. 25 #define DECLARE_CLASS_TYPE_INFO(classname) \ 26 public: \ 27 static const char* TypeName() \ 28 { \ 29 return #classname; \ 30 } \ 31 static TypeInfoBase::IdType TypeId() \ 32 { \ 33 static TypeInfoBase::IdType myTypeId = std::hash<std::string> {}(TypeName()); \ 34 return myTypeId; \ 35 } \ 36 DECLARE_CLASS_TYPE_SIZE(classname) 37 38 // Integrate it into class declaration to support 'DynamicCast'. 39 #define DECLARE_RELATIONSHIP_OF_CLASSES(classname, ...) DECLARE_CLASS_TYPE_INFO(classname) \ 40 protected: \ 41 template<class __T, class __O, class... __V> \ 42 uintptr_t TrySafeCastById(TypeInfoBase::IdType id) const \ 43 { \ 44 VERIFY_DECLARED_CLASS(__T); \ 45 uintptr_t ptr = __T::SafeCastById(id); \ 46 return ptr != 0 ? ptr : TrySafeCastById<__O, __V...>(id); \ 47 } \ 48 template<class __T> \ 49 uintptr_t TrySafeCastById(TypeInfoBase::IdType id) const \ 50 { \ 51 VERIFY_DECLARED_CLASS(__T); \ 52 return __T::SafeCastById(id); \ 53 } \ 54 uintptr_t SafeCastById(TypeInfoBase::IdType id) const override \ 55 { \ 56 return id == TypeId() ? reinterpret_cast<uintptr_t>(this) : TrySafeCastById<__VA_ARGS__>(id); \ 57 } \ 58 TypeInfoBase::IdType GetTypeId() const override \ 59 { \ 60 return TypeId(); \ 61 } \ 62 const char* GetTypeName() const override \ 63 { \ 64 return TypeName(); \ 65 } \ 66 DECLARE_CLASS_GET_TYPE_SIZE(classname) 67 68 namespace OHOS::Ace { 69 70 // Define the base class, inherit this class to support partial 'RTTI' feature. 71 class TypeInfoBase { 72 public: 73 friend class TypeInfoHelper; 74 virtual ~TypeInfoBase() = default; 75 76 using IdType = std::size_t; 77 DECLARE_CLASS_TYPE_INFO(TypeInfoBase); 78 79 protected: SafeCastById(IdType id)80 virtual uintptr_t SafeCastById(IdType id) const 81 { 82 return id == TypeId() ? reinterpret_cast<uintptr_t>(this) : 0; 83 } 84 85 virtual IdType GetTypeId() const = 0; 86 virtual const char* GetTypeName() const = 0; GetTypeSize()87 virtual size_t GetTypeSize() const { return 0; } 88 }; 89 90 class TypeInfoHelper final { 91 public: 92 TypeInfoHelper() = delete; 93 ~TypeInfoHelper() = delete; 94 95 // Convert pointer of instance inherited from 'TypeInfoBase'. 96 // Notice: Result SHOULD BE checked with 'nullptr', because 'DynamicCast' might be failed. 97 template<class T> DynamicCast(TypeInfoBase * rawPtr)98 static T* DynamicCast(TypeInfoBase* rawPtr) 99 { 100 VERIFY_DECLARED_CLASS(T); 101 return rawPtr != nullptr ? reinterpret_cast<T*>(rawPtr->SafeCastById(T::TypeId())) : nullptr; 102 } 103 template<class T> DynamicCast(const TypeInfoBase * rawPtr)104 static const T* DynamicCast(const TypeInfoBase* rawPtr) 105 { 106 VERIFY_DECLARED_CLASS(T); 107 return rawPtr != nullptr ? reinterpret_cast<const T*>(rawPtr->SafeCastById(T::TypeId())) : nullptr; 108 } 109 110 // Get type info by instance. TypeId(const TypeInfoBase * rawPtr)111 static TypeInfoBase::IdType TypeId(const TypeInfoBase* rawPtr) 112 { 113 return rawPtr != nullptr ? rawPtr->GetTypeId() : 0; 114 } TypeId(const TypeInfoBase & instance)115 static TypeInfoBase::IdType TypeId(const TypeInfoBase& instance) 116 { 117 return TypeId(&instance); 118 } TypeName(const TypeInfoBase * rawPtr)119 static const char* TypeName(const TypeInfoBase* rawPtr) 120 { 121 return rawPtr != nullptr ? rawPtr->GetTypeName() : nullptr; 122 } TypeName(const TypeInfoBase & instance)123 static const char* TypeName(const TypeInfoBase& instance) 124 { 125 return TypeName(&instance); 126 } TypeSize(const TypeInfoBase * rawPtr)127 static size_t TypeSize(const TypeInfoBase* rawPtr) 128 { 129 return rawPtr != nullptr ? rawPtr->GetTypeSize() : 0; 130 } TypeSize(const TypeInfoBase & instance)131 static size_t TypeSize(const TypeInfoBase& instance) 132 { 133 return TypeSize(&instance); 134 } 135 136 // Get type info by type itself. 137 template<class T> TypeId()138 static TypeInfoBase::IdType TypeId() 139 { 140 return T::TypeId(); 141 } 142 template<class T> TypeName()143 static const char* TypeName() 144 { 145 return T::TypeName(); 146 } 147 148 // Check whether instance is the specified type 149 template<class T> InstanceOf(const TypeInfoBase * rawPtr)150 static bool InstanceOf(const TypeInfoBase* rawPtr) 151 { 152 return DynamicCast<T>(rawPtr) != nullptr; 153 } 154 template<class T> InstanceOf(const TypeInfoBase & instance)155 static bool InstanceOf(const TypeInfoBase& instance) 156 { 157 return DynamicCast<T>(&instance) != nullptr; 158 } 159 }; 160 161 } // namespace OHOS::Ace 162 163 #endif // FOUNDATION_ACE_FRAMEWORKS_BASE_MEMORY_TYPE_INFO_BASE_H 164