1/** 2 * Copyright (c) 2021-2022 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 LIBPANDABASE_MEM_OBJECT_POINTER_H 17#define LIBPANDABASE_MEM_OBJECT_POINTER_H 18 19#include "mem.h" 20 21namespace panda { 22 23/** 24 * @class ObjectPointer<class Object> 25 * 26 * \brief This class is wrapper for object types. 27 * 28 * Wraps pointer Object * into class ObjectPointer<Object> and provides interfaces to work with it as a pointer. 29 * This is needed to use object pointers of size 32 bits in 64-bit architectures. 30 */ 31template <class Object> 32class ObjectPointer final { 33public: 34 ObjectPointer() = default; 35 // NOLINTNEXTLINE(google-explicit-constructor) 36 ObjectPointer(Object *object) : object_(ToObjPtrType(object)) 37 { 38#ifdef PANDA_USE_32_BIT_POINTER 39 ASSERT(IsInObjectsAddressSpace(ToUintPtr(object))); 40#endif 41 } 42 // NOLINTNEXTLINE(google-explicit-constructor) 43 ObjectPointer(std::nullptr_t a_nullptr) noexcept : object_(ToObjPtrType(a_nullptr)) {} 44 45 DEFAULT_COPY_SEMANTIC(ObjectPointer); 46 DEFAULT_NOEXCEPT_MOVE_SEMANTIC(ObjectPointer); 47 48 ObjectPointer &operator=(std::nullptr_t a_nullptr) 49 { 50 object_ = ToObjPtrType(a_nullptr); 51 return *this; 52 } 53 54 ObjectPointer &operator=(const Object *object) 55 { 56#ifdef PANDA_USE_32_BIT_POINTER 57 ASSERT(IsInObjectsAddressSpace(ToUintPtr(object))); 58#endif 59 object_ = ToObjPtrType(object); 60 return *this; 61 } 62 63 ALWAYS_INLINE Object *operator->() 64 { 65 ASSERT(object_ != 0); 66 return ToObjectPtr(object_); 67 } 68 69 // NOLINTNEXTLINE(google-explicit-constructor) 70 ALWAYS_INLINE operator Object *() 71 { 72 return ToObjectPtr(object_); 73 } 74 75 ALWAYS_INLINE Object &operator*() 76 { 77 ASSERT(object_ != 0); 78 return *ToObjectPtr(object_); 79 } 80 81 ALWAYS_INLINE bool operator==(const ObjectPointer &other) const noexcept 82 { 83 return object_ == other.object_; 84 } 85 86 ALWAYS_INLINE bool operator!=(const ObjectPointer &other) const noexcept 87 { 88 return object_ != other.object_; 89 } 90 91 ALWAYS_INLINE bool operator==(Object *other) const noexcept 92 { 93 return ToObjectPtr(object_) == other; 94 } 95 96 ALWAYS_INLINE bool operator!=(Object *other) const noexcept 97 { 98 return ToObjectPtr(object_) != other; 99 } 100 101 ALWAYS_INLINE bool operator==(std::nullptr_t) const noexcept 102 { 103 return ToObjectPtr(object_) == nullptr; 104 } 105 106 ALWAYS_INLINE bool operator!=(std::nullptr_t) const noexcept 107 { 108 return ToObjectPtr(object_) != nullptr; 109 } 110 111 ALWAYS_INLINE Object &operator[](size_t index) 112 { 113 return ToObjectPtr(object_)[index]; 114 } 115 116 ALWAYS_INLINE const Object &operator[](size_t index) const 117 { 118 return ToObjectPtr(object_)[index]; 119 } 120 121 template <class U> 122 ALWAYS_INLINE U ReinterpretCast() const noexcept 123 { 124 return reinterpret_cast<U>(ToObjectPtr(object_)); 125 } 126 127 ~ObjectPointer() = default; 128 129private: 130 object_pointer_type object_ {}; 131 132 ALWAYS_INLINE static Object *ToObjectPtr(const object_pointer_type pointer) noexcept 133 { 134 return ToNativePtr<Object>(static_cast<uintptr_t>(pointer)); 135 } 136}; 137 138// size of ObjectPointer<T> must be equal size of object_pointer_type 139static_assert(sizeof(ObjectPointer<bool>) == sizeof(object_pointer_type)); 140 141} // namespace panda 142 143#endif // LIBPANDABASE_MEM_OBJECT_POINTER_H 144