1e9297d28Sopenharmony_ci/* 2e9297d28Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3e9297d28Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4e9297d28Sopenharmony_ci * you may not use this file except in compliance with the License. 5e9297d28Sopenharmony_ci * You may obtain a copy of the License at 6e9297d28Sopenharmony_ci * 7e9297d28Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8e9297d28Sopenharmony_ci * 9e9297d28Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10e9297d28Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11e9297d28Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e9297d28Sopenharmony_ci * See the License for the specific language governing permissions and 13e9297d28Sopenharmony_ci * limitations under the License. 14e9297d28Sopenharmony_ci */ 15e9297d28Sopenharmony_ci 16e9297d28Sopenharmony_ci /** 17e9297d28Sopenharmony_ci * @file refbase.h 18e9297d28Sopenharmony_ci * 19e9297d28Sopenharmony_ci * @brief Provide smart pointer implemented in c_utils. 20e9297d28Sopenharmony_ci */ 21e9297d28Sopenharmony_ci 22e9297d28Sopenharmony_ci /** 23e9297d28Sopenharmony_ci * @defgroup SmartPointer 24e9297d28Sopenharmony_ci * @{ 25e9297d28Sopenharmony_ci * @brief Smart Pointer are pointer-like classes. 26e9297d28Sopenharmony_ci * 27e9297d28Sopenharmony_ci * They simulates a pointer while providing added features, 28e9297d28Sopenharmony_ci * such as automatic memory management.\n 29e9297d28Sopenharmony_ci * Automatic memory management is mainly about deallocating 30e9297d28Sopenharmony_ci * the related memory correctly when an object beyonds its life cycle. 31e9297d28Sopenharmony_ci */ 32e9297d28Sopenharmony_ci 33e9297d28Sopenharmony_ci#ifndef UTILS_BASE_REFBASE_H 34e9297d28Sopenharmony_ci#define UTILS_BASE_REFBASE_H 35e9297d28Sopenharmony_ci 36e9297d28Sopenharmony_ci#include <atomic> 37e9297d28Sopenharmony_ci#include <functional> 38e9297d28Sopenharmony_ci#ifdef DEBUG_REFBASE 39e9297d28Sopenharmony_ci#include <mutex> 40e9297d28Sopenharmony_ci#endif 41e9297d28Sopenharmony_ci 42e9297d28Sopenharmony_ci#ifdef _WIN32 43e9297d28Sopenharmony_ci#define RS_EXPORT __attribute__((dllexport)) 44e9297d28Sopenharmony_ci#else 45e9297d28Sopenharmony_ci#define RS_EXPORT __attribute__((visibility("default"))) 46e9297d28Sopenharmony_ci#endif 47e9297d28Sopenharmony_ci 48e9297d28Sopenharmony_cinamespace OHOS { 49e9297d28Sopenharmony_ci/** 50e9297d28Sopenharmony_ci * @ingroup SmartPointer 51e9297d28Sopenharmony_ci * @brief A value indicates no strong references exist ever. 52e9297d28Sopenharmony_ci */ 53e9297d28Sopenharmony_ci#define INITIAL_PRIMARY_VALUE (1 << 28) 54e9297d28Sopenharmony_ci 55e9297d28Sopenharmony_ciclass RefBase; 56e9297d28Sopenharmony_ci 57e9297d28Sopenharmony_ci#ifdef DEBUG_REFBASE 58e9297d28Sopenharmony_ciclass RefTracker; 59e9297d28Sopenharmony_ci#endif 60e9297d28Sopenharmony_ci 61e9297d28Sopenharmony_ci/** 62e9297d28Sopenharmony_ci * @ingroup SmartPointer 63e9297d28Sopenharmony_ci * @brief Reference counter. A class records two kinds of count of references to 64e9297d28Sopenharmony_ci * the corresponding RefBase object, and a count of references to the RefCounter 65e9297d28Sopenharmony_ci * itself. 66e9297d28Sopenharmony_ci * 67e9297d28Sopenharmony_ci * There are two different references for a single object.\n 68e9297d28Sopenharmony_ci * Strong Reference holds a reference directly point to the object. 69e9297d28Sopenharmony_ci * Objects which are strong referenced ought to be alive/existed 70e9297d28Sopenharmony_ci * as long as this strong reference exists, thus the reference 71e9297d28Sopenharmony_ci * is still valid.\n 72e9297d28Sopenharmony_ci * Weak Reference holds a reference indirectly point to the object. 73e9297d28Sopenharmony_ci * Objects which are weak referenced are not guaranteed to be alive/existed 74e9297d28Sopenharmony_ci * even if the weak reference exists. 75e9297d28Sopenharmony_ci * @note Descriptions above are valid only when smart pointers 76e9297d28Sopenharmony_ci * are properly used. 77e9297d28Sopenharmony_ci */ 78e9297d28Sopenharmony_ciclass RefCounter { 79e9297d28Sopenharmony_cipublic: 80e9297d28Sopenharmony_ci /** 81e9297d28Sopenharmony_ci * @brief Callback function to destroy the corresponding RefBase object. 82e9297d28Sopenharmony_ci */ 83e9297d28Sopenharmony_ci using RefPtrCallback = std::function<void()>; 84e9297d28Sopenharmony_ci friend class RefBase; 85e9297d28Sopenharmony_ci 86e9297d28Sopenharmony_ci RefCounter(); 87e9297d28Sopenharmony_ci 88e9297d28Sopenharmony_ci explicit RefCounter(RefCounter *counter); 89e9297d28Sopenharmony_ci 90e9297d28Sopenharmony_ci RefCounter &operator=(const RefCounter &counter); 91e9297d28Sopenharmony_ci 92e9297d28Sopenharmony_ci virtual ~RefCounter(); 93e9297d28Sopenharmony_ci 94e9297d28Sopenharmony_ci /** 95e9297d28Sopenharmony_ci * @brief Set the callback function. 96e9297d28Sopenharmony_ci * 97e9297d28Sopenharmony_ci * @param callback A function to be set to delete 98e9297d28Sopenharmony_ci * the corresponding RefBase object. 99e9297d28Sopenharmony_ci */ 100e9297d28Sopenharmony_ci void SetCallback(const RefPtrCallback& callback); 101e9297d28Sopenharmony_ci 102e9297d28Sopenharmony_ci /** 103e9297d28Sopenharmony_ci * @brief Remove the current callback function. Set it to a `nullptr`. 104e9297d28Sopenharmony_ci */ 105e9297d28Sopenharmony_ci void RemoveCallback(); 106e9297d28Sopenharmony_ci 107e9297d28Sopenharmony_ci /** 108e9297d28Sopenharmony_ci * @brief Get reference count to the RefCounter object. 109e9297d28Sopenharmony_ci * 110e9297d28Sopenharmony_ci * @return Value of the related count. 111e9297d28Sopenharmony_ci */ 112e9297d28Sopenharmony_ci int GetRefCount(); 113e9297d28Sopenharmony_ci 114e9297d28Sopenharmony_ci /** 115e9297d28Sopenharmony_ci * @brief Increment the reference count to the RefCounter object by 1. 116e9297d28Sopenharmony_ci */ 117e9297d28Sopenharmony_ci void IncRefCount(); 118e9297d28Sopenharmony_ci 119e9297d28Sopenharmony_ci /** 120e9297d28Sopenharmony_ci * @brief Decrement the reference count to the RefCounter object by 1. 121e9297d28Sopenharmony_ci * 122e9297d28Sopenharmony_ci * Once the count reaches 0 after being decremented, 123e9297d28Sopenharmony_ci * it will call `delete this` to deallocate this RefCounter object. 124e9297d28Sopenharmony_ci */ 125e9297d28Sopenharmony_ci void DecRefCount(); 126e9297d28Sopenharmony_ci 127e9297d28Sopenharmony_ci /** 128e9297d28Sopenharmony_ci * @brief Check if pointer to the call back function is a `nullptr`. 129e9297d28Sopenharmony_ci * 130e9297d28Sopenharmony_ci * @return Return true if it is not a `nullptr`. 131e9297d28Sopenharmony_ci */ 132e9297d28Sopenharmony_ci bool IsRefPtrValid(); 133e9297d28Sopenharmony_ci 134e9297d28Sopenharmony_ci /** 135e9297d28Sopenharmony_ci * @brief Increment the strong reference count to the 136e9297d28Sopenharmony_ci * corresponding RefBase object by 1. 137e9297d28Sopenharmony_ci * 138e9297d28Sopenharmony_ci * @return Original (before increment) value of the count. 139e9297d28Sopenharmony_ci */ 140e9297d28Sopenharmony_ci int IncStrongRefCount(const void *objectId); 141e9297d28Sopenharmony_ci 142e9297d28Sopenharmony_ci /** 143e9297d28Sopenharmony_ci * @brief Decrement the strong reference count to the 144e9297d28Sopenharmony_ci * corresponding RefBase object by 1. 145e9297d28Sopenharmony_ci * 146e9297d28Sopenharmony_ci * @return Original (before decrement) value of the count. 147e9297d28Sopenharmony_ci * @note If the strong reference has never existed, 148e9297d28Sopenharmony_ci * decrement will cause no effection. 149e9297d28Sopenharmony_ci */ 150e9297d28Sopenharmony_ci int DecStrongRefCount(const void *objectId); 151e9297d28Sopenharmony_ci 152e9297d28Sopenharmony_ci /** 153e9297d28Sopenharmony_ci * @brief Get the strong reference count to the 154e9297d28Sopenharmony_ci * corresponding RefBase object. 155e9297d28Sopenharmony_ci * 156e9297d28Sopenharmony_ci * @return Value of the related count. 157e9297d28Sopenharmony_ci */ 158e9297d28Sopenharmony_ci int GetStrongRefCount(); 159e9297d28Sopenharmony_ci 160e9297d28Sopenharmony_ci /** 161e9297d28Sopenharmony_ci * @brief Increment the weak reference count to the 162e9297d28Sopenharmony_ci * corresponding RefBase object by 1. 163e9297d28Sopenharmony_ci * 164e9297d28Sopenharmony_ci * @return Original (before increment) value of the count. 165e9297d28Sopenharmony_ci */ 166e9297d28Sopenharmony_ci int IncWeakRefCount(const void *objectId); 167e9297d28Sopenharmony_ci 168e9297d28Sopenharmony_ci /** 169e9297d28Sopenharmony_ci * @brief Decrement the weak reference count to the 170e9297d28Sopenharmony_ci * corresponding RefBase object by 1. 171e9297d28Sopenharmony_ci * 172e9297d28Sopenharmony_ci * @return Original (before decrement) value of atomicWeak_. 173e9297d28Sopenharmony_ci * @note When the count reaches 0 after being decremented, the 174e9297d28Sopenharmony_ci * corresponding RefBase object with no strong reference ever, 175e9297d28Sopenharmony_ci * or the object with strong reference count of 0 but has not been 176e9297d28Sopenharmony_ci * deallocated due to its extended 'life time', will be deallocated. 177e9297d28Sopenharmony_ci */ 178e9297d28Sopenharmony_ci int DecWeakRefCount(const void *objectId); 179e9297d28Sopenharmony_ci 180e9297d28Sopenharmony_ci /** 181e9297d28Sopenharmony_ci * @brief Get the weak reference count to the 182e9297d28Sopenharmony_ci * corresponding RefBase object. 183e9297d28Sopenharmony_ci * 184e9297d28Sopenharmony_ci * @return Value of the related count. 185e9297d28Sopenharmony_ci */ 186e9297d28Sopenharmony_ci int GetWeakRefCount(); 187e9297d28Sopenharmony_ci 188e9297d28Sopenharmony_ci /** 189e9297d28Sopenharmony_ci * @brief Increment the times of attempts to increment. 190e9297d28Sopenharmony_ci */ 191e9297d28Sopenharmony_ci void SetAttemptAcquire(); 192e9297d28Sopenharmony_ci 193e9297d28Sopenharmony_ci /** 194e9297d28Sopenharmony_ci * @brief Check if the times of attempts greater than 0. 195e9297d28Sopenharmony_ci * 196e9297d28Sopenharmony_ci * @return Return true if the times is greater than 0. 197e9297d28Sopenharmony_ci */ 198e9297d28Sopenharmony_ci bool IsAttemptAcquireSet(); 199e9297d28Sopenharmony_ci 200e9297d28Sopenharmony_ci /** 201e9297d28Sopenharmony_ci * @brief Clear the times of attempts to increment. 202e9297d28Sopenharmony_ci */ 203e9297d28Sopenharmony_ci void ClearAttemptAcquire(); 204e9297d28Sopenharmony_ci 205e9297d28Sopenharmony_ci /** 206e9297d28Sopenharmony_ci * @brief Attempt to increment the strong reference count to the 207e9297d28Sopenharmony_ci * corresponding RefBase object by 1. 208e9297d28Sopenharmony_ci * 209e9297d28Sopenharmony_ci * @param outCount If the attempt success, the original value 210e9297d28Sopenharmony_ci * (before increment) of the count will be stored here. 211e9297d28Sopenharmony_ci * @return Return true if the attempt success. 212e9297d28Sopenharmony_ci */ 213e9297d28Sopenharmony_ci bool AttemptIncStrongRef(const void *objectId, int &outCount); 214e9297d28Sopenharmony_ci 215e9297d28Sopenharmony_ci // Only for IPC use. 216e9297d28Sopenharmony_ci /** 217e9297d28Sopenharmony_ci * @brief Attempt to increment the strong reference count to 218e9297d28Sopenharmony_ci * the corresponding RefBase object by 1(Simplified). 219e9297d28Sopenharmony_ci * 220e9297d28Sopenharmony_ci * @return Return true if the attempt success. 221e9297d28Sopenharmony_ci * @note Ony for IPC use. 222e9297d28Sopenharmony_ci */ 223e9297d28Sopenharmony_ci bool AttemptIncStrong(const void *objectId); 224e9297d28Sopenharmony_ci 225e9297d28Sopenharmony_ci /** 226e9297d28Sopenharmony_ci * @brief Check if the corresponding RefBase object 227e9297d28Sopenharmony_ci * own an extended life-time. 228e9297d28Sopenharmony_ci * 229e9297d28Sopenharmony_ci * @return Return true if its life-time has been extended. 230e9297d28Sopenharmony_ci */ 231e9297d28Sopenharmony_ci bool IsLifeTimeExtended(); 232e9297d28Sopenharmony_ci 233e9297d28Sopenharmony_ci /** 234e9297d28Sopenharmony_ci * @brief Extend the life-time of corresponding RefBase object. 235e9297d28Sopenharmony_ci * 236e9297d28Sopenharmony_ci * It allows the corresponding object keep alive 237e9297d28Sopenharmony_ci * even if there exists no strong reference to it. 238e9297d28Sopenharmony_ci * @note Corresponding object will be deallocated 239e9297d28Sopenharmony_ci * when related weak reference count also reach 0. 240e9297d28Sopenharmony_ci */ 241e9297d28Sopenharmony_ci void ExtendObjectLifetime(); 242e9297d28Sopenharmony_ci 243e9297d28Sopenharmony_ciprivate: 244e9297d28Sopenharmony_ci std::atomic<int> atomicStrong_; // = (num of sptr) or Initial-value 245e9297d28Sopenharmony_ci std::atomic<int> atomicWeak_; // = (num of sptr)+(num of WeakRefCounter) 246e9297d28Sopenharmony_ci std::atomic<int> atomicRefCount_; // = (num of WeakRefCounter) + 1 247e9297d28Sopenharmony_ci std::atomic<unsigned int> atomicFlags_; // A life-time extended flag 248e9297d28Sopenharmony_ci std::atomic<int> atomicAttempt_; // Times of attempts 249e9297d28Sopenharmony_ci RefPtrCallback callback_ = nullptr; // A callback function to deallocate the corresponding RefBase object 250e9297d28Sopenharmony_ci static constexpr unsigned int FLAG_EXTEND_LIFE_TIME = 0x00000002; // Extended life-time bit to be set via logic-OR 251e9297d28Sopenharmony_ci#ifdef DEBUG_REFBASE 252e9297d28Sopenharmony_ci RefTracker* refTracker = nullptr; 253e9297d28Sopenharmony_ci std::mutex trackerMutex; // To ensure refTracker be thread-safe 254e9297d28Sopenharmony_ci void GetNewTrace(const void* objectId); 255e9297d28Sopenharmony_ci void PrintTracker(); 256e9297d28Sopenharmony_ci#endif 257e9297d28Sopenharmony_ci}; 258e9297d28Sopenharmony_ci 259e9297d28Sopenharmony_ci#ifdef DEBUG_REFBASE 260e9297d28Sopenharmony_ci// RefTracker is a debug tool, used to record the trace of RefBase. 261e9297d28Sopenharmony_ci// RefTracker will save the information about the count of RefBase, 262e9297d28Sopenharmony_ci// including the pointer of sptr/wptr(The pointer of itself, not the pointer 263e9297d28Sopenharmony_ci// it manages), the amount of strong/weak/refcout and the PID&TID. 264e9297d28Sopenharmony_ci// The Tracker can live with RefCounter/RefBase(including its derivation). 265e9297d28Sopenharmony_ci// User should keep thread-safety of RefTracker. 266e9297d28Sopenharmony_ciclass RefTracker { 267e9297d28Sopenharmony_cipublic: 268e9297d28Sopenharmony_ci RefTracker() {}; 269e9297d28Sopenharmony_ci 270e9297d28Sopenharmony_ci RefTracker(RefTracker* exTracker, const void* id, int strong, int weak, int ref, int pid, int tid); 271e9297d28Sopenharmony_ci 272e9297d28Sopenharmony_ci void GetTrace(RefTracker* exTracker, const void* id, int strong, int weak, int ref, int pid, int tid); 273e9297d28Sopenharmony_ci 274e9297d28Sopenharmony_ci // Only used for tracking the amount of Strong Reference. 275e9297d28Sopenharmony_ci void GetStrongTrace(RefTracker* exTracker, const void* id, int strong, int pid, int tid); 276e9297d28Sopenharmony_ci 277e9297d28Sopenharmony_ci // Only used for tracking the amount of Weak Reference. 278e9297d28Sopenharmony_ci void GetWeakTrace(RefTracker* exTracker, const void* id, int weak, int pid, int tid); 279e9297d28Sopenharmony_ci 280e9297d28Sopenharmony_ci void PrintTrace(const void* root); 281e9297d28Sopenharmony_ci 282e9297d28Sopenharmony_ci void PrintStrongTrace(const void* root); 283e9297d28Sopenharmony_ci 284e9297d28Sopenharmony_ci void PrintWeakTrace(const void* root); 285e9297d28Sopenharmony_ci 286e9297d28Sopenharmony_ci RefTracker* GetexTrace(); 287e9297d28Sopenharmony_ci 288e9297d28Sopenharmony_ci RefTracker* PopTrace(const void* root); 289e9297d28Sopenharmony_ci 290e9297d28Sopenharmony_ciprivate: 291e9297d28Sopenharmony_ci const void* ptrID; 292e9297d28Sopenharmony_ci int strongRefCNT; 293e9297d28Sopenharmony_ci int weakRefCNT; 294e9297d28Sopenharmony_ci int refCNT; 295e9297d28Sopenharmony_ci int PID; 296e9297d28Sopenharmony_ci int TID; 297e9297d28Sopenharmony_ci RefTracker* exTrace; 298e9297d28Sopenharmony_ci}; 299e9297d28Sopenharmony_ci#endif 300e9297d28Sopenharmony_ci 301e9297d28Sopenharmony_ci/** 302e9297d28Sopenharmony_ci * @ingroup SmartPointer 303e9297d28Sopenharmony_ci * @brief An intermediate class to represent the weak reference 304e9297d28Sopenharmony_ci * to the correspond RefBase object. 305e9297d28Sopenharmony_ci * 306e9297d28Sopenharmony_ci * A WeakRefCounter object can be held by multiple wptr objects.\n 307e9297d28Sopenharmony_ci * It holds references to the corresponding RefBase and RefCounter object. 308e9297d28Sopenharmony_ci * Those two references will be set as `nullptr`s, when the weak referenced 309e9297d28Sopenharmony_ci * target and its RefCounter object has been deallocated. Thus WeakRefCounter 310e9297d28Sopenharmony_ci * object can still alive even if the target refereneced by this object 311e9297d28Sopenharmony_ci * is vanished. 312e9297d28Sopenharmony_ci */ 313e9297d28Sopenharmony_ciclass WeakRefCounter { 314e9297d28Sopenharmony_cipublic: 315e9297d28Sopenharmony_ci /** 316e9297d28Sopenharmony_ci * @brief Construct a new Weak Ref Counter object. 317e9297d28Sopenharmony_ci * 318e9297d28Sopenharmony_ci * @param counter Pointer to corresponding RefCounter object. 319e9297d28Sopenharmony_ci * @param cookie Pointer to corresponding RefBase object. 320e9297d28Sopenharmony_ci */ 321e9297d28Sopenharmony_ci WeakRefCounter(RefCounter *counter, void *cookie); 322e9297d28Sopenharmony_ci 323e9297d28Sopenharmony_ci virtual ~WeakRefCounter(); 324e9297d28Sopenharmony_ci 325e9297d28Sopenharmony_ci /** 326e9297d28Sopenharmony_ci * @brief Get current pointer to the corresponding RefBase object. 327e9297d28Sopenharmony_ci * 328e9297d28Sopenharmony_ci * @return A void pointer to the RefBase object. 329e9297d28Sopenharmony_ci * If the corresponding object does not alive, a `nullptr` will return. 330e9297d28Sopenharmony_ci * @note Void pointer means you should cast it to the real type, since it 331e9297d28Sopenharmony_ci * can be kinds of subclasses of RefBase. 332e9297d28Sopenharmony_ci */ 333e9297d28Sopenharmony_ci void *GetRefPtr(); 334e9297d28Sopenharmony_ci 335e9297d28Sopenharmony_ci /** 336e9297d28Sopenharmony_ci * @brief Increment the reference count to this WeakRefCounter object. 337e9297d28Sopenharmony_ci * 338e9297d28Sopenharmony_ci * @note Notice the difference between this count and the weak reference 339e9297d28Sopenharmony_ci * count in RefCounter. This value equals to the number of wptrs directly 340e9297d28Sopenharmony_ci * referencing this WeakRefCount object. 341e9297d28Sopenharmony_ci * @see RefCounter 342e9297d28Sopenharmony_ci */ 343e9297d28Sopenharmony_ci void IncWeakRefCount(const void *objectId); 344e9297d28Sopenharmony_ci 345e9297d28Sopenharmony_ci /** 346e9297d28Sopenharmony_ci * @brief Decrement the reference count to this WeakRefCounter object. 347e9297d28Sopenharmony_ci * 348e9297d28Sopenharmony_ci * @note This WeakRefCounter object will be deallocated when this count 349e9297d28Sopenharmony_ci * reaches 0. 350e9297d28Sopenharmony_ci */ 351e9297d28Sopenharmony_ci void DecWeakRefCount(const void *objectId); 352e9297d28Sopenharmony_ci 353e9297d28Sopenharmony_ci /** 354e9297d28Sopenharmony_ci * @brief Get the count recorded by this WeakRefCounter object. 355e9297d28Sopenharmony_ci * 356e9297d28Sopenharmony_ci * @return Value of the count. 357e9297d28Sopenharmony_ci * @note This value of count is different from that in RefCounter. 358e9297d28Sopenharmony_ci * @see RefCounter::GetWeakRefCount() 359e9297d28Sopenharmony_ci */ 360e9297d28Sopenharmony_ci int GetWeakRefCount() const; 361e9297d28Sopenharmony_ci 362e9297d28Sopenharmony_ci /** 363e9297d28Sopenharmony_ci * @brief Attempt to increment the strong reference count of 364e9297d28Sopenharmony_ci * the corresponding RefBase object(Used in promoting a wptr to a sptr). 365e9297d28Sopenharmony_ci * 366e9297d28Sopenharmony_ci * @return Return `true` after a success increment. 367e9297d28Sopenharmony_ci */ 368e9297d28Sopenharmony_ci bool AttemptIncStrongRef(const void *objectId); 369e9297d28Sopenharmony_ci 370e9297d28Sopenharmony_ciprivate: 371e9297d28Sopenharmony_ci std::atomic<int> atomicWeak_; // Count of references to this WeakRefCounter object 372e9297d28Sopenharmony_ci // The value equals to the total amount of wptrs which 373e9297d28Sopenharmony_ci // reference this WeakRefCounter object 374e9297d28Sopenharmony_ci RefCounter *refCounter_ = nullptr; // reference to the RefCounter object of corresponding RefBase Object 375e9297d28Sopenharmony_ci void *cookie_ = nullptr; // Pointer to the corresponding RefBase object 376e9297d28Sopenharmony_ci}; 377e9297d28Sopenharmony_ci 378e9297d28Sopenharmony_ci/** 379e9297d28Sopenharmony_ci * @ingroup SmartPointer 380e9297d28Sopenharmony_ci * @brief A base class which can be managed by a smart pointer. 381e9297d28Sopenharmony_ci * 382e9297d28Sopenharmony_ci * @note All classes which intend to be managed by smart pointers should be 383e9297d28Sopenharmony_ci * derived from RefBase. 384e9297d28Sopenharmony_ci */ 385e9297d28Sopenharmony_ciclass RS_EXPORT RefBase { 386e9297d28Sopenharmony_cipublic: 387e9297d28Sopenharmony_ci RefBase(); 388e9297d28Sopenharmony_ci 389e9297d28Sopenharmony_ci /** 390e9297d28Sopenharmony_ci * @brief Copy constructor of RefBase. 391e9297d28Sopenharmony_ci * 392e9297d28Sopenharmony_ci * @note Note that this method will construct a new RefCounter object, 393e9297d28Sopenharmony_ci * and bind with it. 394e9297d28Sopenharmony_ci */ 395e9297d28Sopenharmony_ci RefBase(const RefBase &); 396e9297d28Sopenharmony_ci 397e9297d28Sopenharmony_ci /** 398e9297d28Sopenharmony_ci * @brief Copy assignment operator of RefBase. 399e9297d28Sopenharmony_ci * 400e9297d28Sopenharmony_ci * @note This method will unbind the current RefBase object and its 401e9297d28Sopenharmony_ci * original RefCounter object, then bind a newly constructed 402e9297d28Sopenharmony_ci * RefCounter object. 403e9297d28Sopenharmony_ci */ 404e9297d28Sopenharmony_ci RefBase &operator=(const RefBase &); 405e9297d28Sopenharmony_ci 406e9297d28Sopenharmony_ci /** 407e9297d28Sopenharmony_ci * @brief Move constructor of RefBase. 408e9297d28Sopenharmony_ci */ 409e9297d28Sopenharmony_ci RefBase(RefBase &&other) noexcept; 410e9297d28Sopenharmony_ci 411e9297d28Sopenharmony_ci /** 412e9297d28Sopenharmony_ci * @brief Move assignment operator of RefBase. 413e9297d28Sopenharmony_ci * 414e9297d28Sopenharmony_ci * @note This method will bind this RefBase object with the RefCounter 415e9297d28Sopenharmony_ci * object of the argument `other`, then `other` will unbind the RefCounter 416e9297d28Sopenharmony_ci * object.\n No counts operation will be poccessed. 417e9297d28Sopenharmony_ci */ 418e9297d28Sopenharmony_ci RefBase &operator=(RefBase &&other) noexcept; 419e9297d28Sopenharmony_ci 420e9297d28Sopenharmony_ci virtual ~RefBase(); 421e9297d28Sopenharmony_ci 422e9297d28Sopenharmony_ci /** 423e9297d28Sopenharmony_ci * @brief A callback method to deallocate this object. 424e9297d28Sopenharmony_ci * 425e9297d28Sopenharmony_ci * This method has default implement to simply deallocate this RefBase 426e9297d28Sopenharmony_ci * object simply by calling `delete(this)`. 427e9297d28Sopenharmony_ci */ 428e9297d28Sopenharmony_ci virtual void RefPtrCallback(); 429e9297d28Sopenharmony_ci 430e9297d28Sopenharmony_ci /** 431e9297d28Sopenharmony_ci * @brief Extend life time of the RefBase object. 432e9297d28Sopenharmony_ci * 433e9297d28Sopenharmony_ci * @note The object whose life time has been extended will not be 434e9297d28Sopenharmony_ci * deallocated when the the weak reference count reach 0 instead of the 435e9297d28Sopenharmony_ci * strong one. 436e9297d28Sopenharmony_ci */ 437e9297d28Sopenharmony_ci void ExtendObjectLifetime(); 438e9297d28Sopenharmony_ci 439e9297d28Sopenharmony_ci /** 440e9297d28Sopenharmony_ci * @brief Increment the strong reference count. 441e9297d28Sopenharmony_ci * 442e9297d28Sopenharmony_ci * `OnFirstStrongRef()`, which is an empty method by default, will be 443e9297d28Sopenharmony_ci * called when the first strong reference are established.、 444e9297d28Sopenharmony_ci * 445e9297d28Sopenharmony_ci * @note It will atomically increment the weak reference count meanwhile. 446e9297d28Sopenharmony_ci */ 447e9297d28Sopenharmony_ci void IncStrongRef(const void *objectId); 448e9297d28Sopenharmony_ci 449e9297d28Sopenharmony_ci /** 450e9297d28Sopenharmony_ci * @brief Decrement the strong reference count. 451e9297d28Sopenharmony_ci * 452e9297d28Sopenharmony_ci * This object will be deallocated when the count reaches 0, if it owns a 453e9297d28Sopenharmony_ci * normal life time.\n `OnLastStrongRef()`, which is an empty method by 454e9297d28Sopenharmony_ci * default, will be called when the last strong reference vanishes. 455e9297d28Sopenharmony_ci */ 456e9297d28Sopenharmony_ci void DecStrongRef(const void *objectId); 457e9297d28Sopenharmony_ci 458e9297d28Sopenharmony_ci /** 459e9297d28Sopenharmony_ci * @brief Get the strong reference count. 460e9297d28Sopenharmony_ci * 461e9297d28Sopenharmony_ci * @return Related count value. Return 0 when corresponding RefCounter 462e9297d28Sopenharmony_ci * object does not exist. 463e9297d28Sopenharmony_ci * @note Only valid when corresponding RefCounter object exists. 464e9297d28Sopenharmony_ci */ 465e9297d28Sopenharmony_ci int GetSptrRefCount(); 466e9297d28Sopenharmony_ci 467e9297d28Sopenharmony_ci /** 468e9297d28Sopenharmony_ci * @brief Create weak reference to this RefBase object. 469e9297d28Sopenharmony_ci * 470e9297d28Sopenharmony_ci * Create a WeakRefCounter object which holds reference to this RefBase 471e9297d28Sopenharmony_ci * object and set the reference count. 472e9297d28Sopenharmony_ci * 473e9297d28Sopenharmony_ci * @param cookie Void pointer to this RefBase object. 474e9297d28Sopenharmony_ci * @return Pointer to the newly created WeakRefCounter object. 475e9297d28Sopenharmony_ci * @note Avoid using it independently. Use related methods of wptr. 476e9297d28Sopenharmony_ci */ 477e9297d28Sopenharmony_ci WeakRefCounter *CreateWeakRef(void *cookie); 478e9297d28Sopenharmony_ci 479e9297d28Sopenharmony_ci /** 480e9297d28Sopenharmony_ci * @brief Get the pointer to corresponding counter object. 481e9297d28Sopenharmony_ci * 482e9297d28Sopenharmony_ci * @return Pointer to the counter object. 483e9297d28Sopenharmony_ci */ 484e9297d28Sopenharmony_ci RefCounter *GetRefCounter() const; 485e9297d28Sopenharmony_ci 486e9297d28Sopenharmony_ci /** 487e9297d28Sopenharmony_ci * @brief Increment the weak reference count. 488e9297d28Sopenharmony_ci * 489e9297d28Sopenharmony_ci * @note Only valid when corresponding RefCounter object exists. 490e9297d28Sopenharmony_ci */ 491e9297d28Sopenharmony_ci void IncWeakRef(const void *objectId); 492e9297d28Sopenharmony_ci 493e9297d28Sopenharmony_ci /** 494e9297d28Sopenharmony_ci * @brief Decrement the weak reference count. 495e9297d28Sopenharmony_ci * 496e9297d28Sopenharmony_ci * @note Only valid when corresponding RefCounter object exists. 497e9297d28Sopenharmony_ci */ 498e9297d28Sopenharmony_ci void DecWeakRef(const void *objectId); 499e9297d28Sopenharmony_ci 500e9297d28Sopenharmony_ci /** 501e9297d28Sopenharmony_ci * @brief Get the weak reference count. 502e9297d28Sopenharmony_ci * 503e9297d28Sopenharmony_ci * @return Value of related count. Return 0 when corresponding 504e9297d28Sopenharmony_ci * RefCounter object doesn't exist. 505e9297d28Sopenharmony_ci */ 506e9297d28Sopenharmony_ci int GetWptrRefCount(); 507e9297d28Sopenharmony_ci 508e9297d28Sopenharmony_ci /** 509e9297d28Sopenharmony_ci * @brief Attempt to increment the strong reference count. 510e9297d28Sopenharmony_ci * 511e9297d28Sopenharmony_ci * `OnFirstStrongRef()`, which is an empty method by default, will be 512e9297d28Sopenharmony_ci * called when the first strong reference are established. 513e9297d28Sopenharmony_ci * 514e9297d28Sopenharmony_ci * @return Return true if successfully increment the count. 515e9297d28Sopenharmony_ci * @note Note that count of times of attempts will increment by 1 516e9297d28Sopenharmony_ci * after a successful increment. 517e9297d28Sopenharmony_ci */ 518e9297d28Sopenharmony_ci bool AttemptAcquire(const void *objectId); 519e9297d28Sopenharmony_ci 520e9297d28Sopenharmony_ci /** 521e9297d28Sopenharmony_ci * @brief Attempt to increment the strong reference count. 522e9297d28Sopenharmony_ci * 523e9297d28Sopenharmony_ci * `OnFirstStrongRef()`, which is an empty method by default, will be 524e9297d28Sopenharmony_ci * called when the first strong reference are established. 525e9297d28Sopenharmony_ci * @return Return true if successfully increment the count. 526e9297d28Sopenharmony_ci * @note Used in various copy constructor of sptr in scenario of 527e9297d28Sopenharmony_ci * interaction between sptr and wptr. Avoid using it independently. 528e9297d28Sopenharmony_ci */ 529e9297d28Sopenharmony_ci bool AttemptIncStrongRef(const void *objectId); 530e9297d28Sopenharmony_ci 531e9297d28Sopenharmony_ci // Only for IPC use. 532e9297d28Sopenharmony_ci /** 533e9297d28Sopenharmony_ci * @brief Attempt to increment the strong reference count. 534e9297d28Sopenharmony_ci * 535e9297d28Sopenharmony_ci * @return Return true if successfully increment the count, otherwise 536e9297d28Sopenharmony_ci * return false. 537e9297d28Sopenharmony_ci * @note Note that times of successful attempts will increment by 1 after 538e9297d28Sopenharmony_ci * a successful increment of the related count. 539e9297d28Sopenharmony_ci * @note This method is a simplified version of `AttemptAcquire`, but only 540e9297d28Sopenharmony_ci * for IPC use. 541e9297d28Sopenharmony_ci */ 542e9297d28Sopenharmony_ci bool AttemptIncStrong(const void *objectId); 543e9297d28Sopenharmony_ci 544e9297d28Sopenharmony_ci /** 545e9297d28Sopenharmony_ci * @brief check if the times of successful attempts of greater than 0. 546e9297d28Sopenharmony_ci * 547e9297d28Sopenharmony_ci * @return Return true if times of successful attempts is greater than 0; 548e9297d28Sopenharmony_ci * Return false if it is not greater than 0, or the corresponding 549e9297d28Sopenharmony_ci * RefCounter object does not exist. 550e9297d28Sopenharmony_ci */ 551e9297d28Sopenharmony_ci bool IsAttemptAcquireSet(); 552e9297d28Sopenharmony_ci 553e9297d28Sopenharmony_ci /** 554e9297d28Sopenharmony_ci * @brief Check if the life time of this RefBase object has been extended. 555e9297d28Sopenharmony_ci * 556e9297d28Sopenharmony_ci * @return Return false when have a normal life time, or the corresponding 557e9297d28Sopenharmony_ci * RefCounter object does not exist. 558e9297d28Sopenharmony_ci */ 559e9297d28Sopenharmony_ci bool IsExtendLifeTimeSet(); 560e9297d28Sopenharmony_ci 561e9297d28Sopenharmony_ci /** 562e9297d28Sopenharmony_ci * @brief An event-drive method, which will be automatically called when 563e9297d28Sopenharmony_ci * first strong reference comes up. 564e9297d28Sopenharmony_ci * 565e9297d28Sopenharmony_ci * @note It is an empty function by default. 566e9297d28Sopenharmony_ci */ 567e9297d28Sopenharmony_ci virtual void OnFirstStrongRef(const void *); 568e9297d28Sopenharmony_ci 569e9297d28Sopenharmony_ci /** 570e9297d28Sopenharmony_ci * @brief An event-drive method, which will be automatically called when 571e9297d28Sopenharmony_ci * last strong reference eliminates. 572e9297d28Sopenharmony_ci * 573e9297d28Sopenharmony_ci * @note It is an empty function by default. 574e9297d28Sopenharmony_ci */ 575e9297d28Sopenharmony_ci virtual void OnLastStrongRef(const void *); 576e9297d28Sopenharmony_ci 577e9297d28Sopenharmony_ci /** 578e9297d28Sopenharmony_ci * @brief An event-drive method, which will be automatically called when 579e9297d28Sopenharmony_ci * last weak reference eliminates. 580e9297d28Sopenharmony_ci * 581e9297d28Sopenharmony_ci * @note It is an empty function by default. 582e9297d28Sopenharmony_ci */ 583e9297d28Sopenharmony_ci virtual void OnLastWeakRef(const void *); 584e9297d28Sopenharmony_ci 585e9297d28Sopenharmony_ci /** 586e9297d28Sopenharmony_ci * @brief An event-drive method, which will be autmatically called when 587e9297d28Sopenharmony_ci * use `wptr::Promote()`. 588e9297d28Sopenharmony_ci * 589e9297d28Sopenharmony_ci * @note Directly return true by default. 590e9297d28Sopenharmony_ci * @return Return true if success, otherwise return false. 591e9297d28Sopenharmony_ci */ 592e9297d28Sopenharmony_ci virtual bool OnAttemptPromoted(const void *); 593e9297d28Sopenharmony_ci 594e9297d28Sopenharmony_ciprivate: 595e9297d28Sopenharmony_ci RefCounter *refs_ = nullptr; // Pointer to the corresponding reference counter of this RefBase object 596e9297d28Sopenharmony_ci}; 597e9297d28Sopenharmony_ci 598e9297d28Sopenharmony_citemplate <typename T> 599e9297d28Sopenharmony_ciclass wptr; 600e9297d28Sopenharmony_ci 601e9297d28Sopenharmony_ci/** 602e9297d28Sopenharmony_ci * @ingroup SmartPointer 603e9297d28Sopenharmony_ci * @brief Strong reference smart pointer to a RefBase(or its subclass) object. 604e9297d28Sopenharmony_ci * 605e9297d28Sopenharmony_ci * It directly reference the RefBase object. 606e9297d28Sopenharmony_ci * 607e9297d28Sopenharmony_ci * @tparam T Specific class type managed by sptr. This class must inherit 608e9297d28Sopenharmony_ci * from RefBase. 609e9297d28Sopenharmony_ci */ 610e9297d28Sopenharmony_citemplate <typename T> 611e9297d28Sopenharmony_ciclass sptr { 612e9297d28Sopenharmony_ci friend class wptr<T>; 613e9297d28Sopenharmony_ci 614e9297d28Sopenharmony_cipublic: 615e9297d28Sopenharmony_ci sptr(); 616e9297d28Sopenharmony_ci 617e9297d28Sopenharmony_ci ~sptr(); 618e9297d28Sopenharmony_ci 619e9297d28Sopenharmony_ci /** 620e9297d28Sopenharmony_ci * @brief Constructor with specified object to be managed. 621e9297d28Sopenharmony_ci * 622e9297d28Sopenharmony_ci * @note Null sptr will be created if `other` is a `nullptr`. 623e9297d28Sopenharmony_ci * @param other Object to be managed by wptr. 624e9297d28Sopenharmony_ci */ 625e9297d28Sopenharmony_ci sptr(T *other); 626e9297d28Sopenharmony_ci 627e9297d28Sopenharmony_ci /** 628e9297d28Sopenharmony_ci * @brief Copy Constructor for sptr with different managed class type(T). 629e9297d28Sopenharmony_ci * 630e9297d28Sopenharmony_ci * @param other Input sptr object. 631e9297d28Sopenharmony_ci */ 632e9297d28Sopenharmony_ci sptr(const sptr<T> &other); 633e9297d28Sopenharmony_ci 634e9297d28Sopenharmony_ci /** 635e9297d28Sopenharmony_ci * @brief Move constructor. 636e9297d28Sopenharmony_ci * 637e9297d28Sopenharmony_ci * @note `other` will be set to a null sptr. 638e9297d28Sopenharmony_ci * @param other Input sptr object. 639e9297d28Sopenharmony_ci */ 640e9297d28Sopenharmony_ci sptr(sptr<T> &&other); 641e9297d28Sopenharmony_ci 642e9297d28Sopenharmony_ci /** 643e9297d28Sopenharmony_ci * @brief Move assignment operator. 644e9297d28Sopenharmony_ci * 645e9297d28Sopenharmony_ci * @param other Input sptr object. 646e9297d28Sopenharmony_ci * @note Original strong reference in target sptr object will be removed. 647e9297d28Sopenharmony_ci */ 648e9297d28Sopenharmony_ci sptr<T> &operator=(sptr<T> &&other); 649e9297d28Sopenharmony_ci 650e9297d28Sopenharmony_ci /** 651e9297d28Sopenharmony_ci * @brief Copy Constructor for sptr with different managed class type(O). 652e9297d28Sopenharmony_ci * 653e9297d28Sopenharmony_ci * @tparam O Another specific class type managed by `other`. 654e9297d28Sopenharmony_ci * @param other Input sptr object. 655e9297d28Sopenharmony_ci */ 656e9297d28Sopenharmony_ci template <typename O> 657e9297d28Sopenharmony_ci sptr(const sptr<O> &other); 658e9297d28Sopenharmony_ci 659e9297d28Sopenharmony_ci /** 660e9297d28Sopenharmony_ci * @brief Constructor only used in promote process of wptr. 661e9297d28Sopenharmony_ci * 662e9297d28Sopenharmony_ci * @param p WeakRefCounter object which hold the reference to the 663e9297d28Sopenharmony_ci * managed object. 664e9297d28Sopenharmony_ci * @param force Only used to identify from other constructor. 665e9297d28Sopenharmony_ci */ 666e9297d28Sopenharmony_ci inline sptr(WeakRefCounter *p, bool force); 667e9297d28Sopenharmony_ci 668e9297d28Sopenharmony_ci /** 669e9297d28Sopenharmony_ci * @brief Get the pointer to the managed object. 670e9297d28Sopenharmony_ci * 671e9297d28Sopenharmony_ci * @return Pointer of the specific managed class type. 672e9297d28Sopenharmony_ci */ 673e9297d28Sopenharmony_ci inline T *GetRefPtr() const 674e9297d28Sopenharmony_ci { 675e9297d28Sopenharmony_ci return refs_; 676e9297d28Sopenharmony_ci } 677e9297d28Sopenharmony_ci 678e9297d28Sopenharmony_ci /** 679e9297d28Sopenharmony_ci * @brief Set the pointer to the managed object. 680e9297d28Sopenharmony_ci * 681e9297d28Sopenharmony_ci * @param other Another pointer object to be managed by sptr. 682e9297d28Sopenharmony_ci * @note Avoid using independently, otherwise it will 683e9297d28Sopenharmony_ci * cause mismatch of reference count and thus memory problems. 684e9297d28Sopenharmony_ci */ 685e9297d28Sopenharmony_ci inline void ForceSetRefPtr(T *other); 686e9297d28Sopenharmony_ci 687e9297d28Sopenharmony_ci /** 688e9297d28Sopenharmony_ci * @brief Remove the reference to the managed object held by current sptr. 689e9297d28Sopenharmony_ci * 690e9297d28Sopenharmony_ci * @note It will make this sptr a "null sptr". 691e9297d28Sopenharmony_ci */ 692e9297d28Sopenharmony_ci void clear(); 693e9297d28Sopenharmony_ci 694e9297d28Sopenharmony_ci /** 695e9297d28Sopenharmony_ci * @brief Type conversion operator. 696e9297d28Sopenharmony_ci * 697e9297d28Sopenharmony_ci * @return Raw pointer to the managed object. 698e9297d28Sopenharmony_ci * @note Sptr object itself will not be converted, only the member raw 699e9297d28Sopenharmony_ci * pointer returns. 700e9297d28Sopenharmony_ci */ 701e9297d28Sopenharmony_ci inline operator T *() const 702e9297d28Sopenharmony_ci { 703e9297d28Sopenharmony_ci return refs_; 704e9297d28Sopenharmony_ci } 705e9297d28Sopenharmony_ci 706e9297d28Sopenharmony_ci /** 707e9297d28Sopenharmony_ci * @brief Dereference operator. 708e9297d28Sopenharmony_ci * 709e9297d28Sopenharmony_ci * It will return the object managed by this sptr. 710e9297d28Sopenharmony_ci * 711e9297d28Sopenharmony_ci * @return Return reference of specific object managed by sptr. 712e9297d28Sopenharmony_ci */ 713e9297d28Sopenharmony_ci inline T &operator*() const 714e9297d28Sopenharmony_ci { 715e9297d28Sopenharmony_ci return *refs_; 716e9297d28Sopenharmony_ci } 717e9297d28Sopenharmony_ci 718e9297d28Sopenharmony_ci /** 719e9297d28Sopenharmony_ci * @brief Member selection operator. 720e9297d28Sopenharmony_ci * 721e9297d28Sopenharmony_ci * It will return the specified member of the object managed by this sptr. 722e9297d28Sopenharmony_ci */ 723e9297d28Sopenharmony_ci inline T *operator->() const 724e9297d28Sopenharmony_ci { 725e9297d28Sopenharmony_ci return refs_; 726e9297d28Sopenharmony_ci } 727e9297d28Sopenharmony_ci 728e9297d28Sopenharmony_ci /** 729e9297d28Sopenharmony_ci * @brief Logical-NOT operator. Check if sptr is a "null sptr". 730e9297d28Sopenharmony_ci * 731e9297d28Sopenharmony_ci * @return Return true if sptr is a "null sptr". 732e9297d28Sopenharmony_ci */ 733e9297d28Sopenharmony_ci inline bool operator!() const 734e9297d28Sopenharmony_ci { 735e9297d28Sopenharmony_ci return refs_ == nullptr; 736e9297d28Sopenharmony_ci } 737e9297d28Sopenharmony_ci 738e9297d28Sopenharmony_ci /** 739e9297d28Sopenharmony_ci * @brief Copy assignment operator with specified object to be managed. 740e9297d28Sopenharmony_ci * 741e9297d28Sopenharmony_ci * @note Original reference will be removed, then new reference to the 742e9297d28Sopenharmony_ci * input object will be established. 743e9297d28Sopenharmony_ci * @param other Another object to be managed by this sptr. 744e9297d28Sopenharmony_ci */ 745e9297d28Sopenharmony_ci sptr<T> &operator=(T *other); 746e9297d28Sopenharmony_ci 747e9297d28Sopenharmony_ci /** 748e9297d28Sopenharmony_ci * @brief Copy assignment operator for sptr with 749e9297d28Sopenharmony_ci * same managed class type(T). 750e9297d28Sopenharmony_ci * 751e9297d28Sopenharmony_ci * @note Original reference will be removed, this sptr will manage the 752e9297d28Sopenharmony_ci * same object with the input sptr object. 753e9297d28Sopenharmony_ci * @param other Another sptr object with same managed class type(T). 754e9297d28Sopenharmony_ci */ 755e9297d28Sopenharmony_ci sptr<T> &operator=(const sptr<T> &other); 756e9297d28Sopenharmony_ci 757e9297d28Sopenharmony_ci /** 758e9297d28Sopenharmony_ci * @brief Copy assignment operator for wptr with 759e9297d28Sopenharmony_ci * same managed class type(T). 760e9297d28Sopenharmony_ci * 761e9297d28Sopenharmony_ci * @note Original reference will be removed, this sptr will manage the 762e9297d28Sopenharmony_ci * same object with the input wptr object. 763e9297d28Sopenharmony_ci * @note This may fail, then this sptr will turn to be a "null sptr". 764e9297d28Sopenharmony_ci * @param other Another wptr object with same managed class type(T). 765e9297d28Sopenharmony_ci */ 766e9297d28Sopenharmony_ci sptr<T> &operator=(const wptr<T> &other); 767e9297d28Sopenharmony_ci 768e9297d28Sopenharmony_ci /** 769e9297d28Sopenharmony_ci * @brief Copy assignment operator for sptr with 770e9297d28Sopenharmony_ci * different managed class type(O). 771e9297d28Sopenharmony_ci * 772e9297d28Sopenharmony_ci * @note Original reference will be removed, this sptr will manage the 773e9297d28Sopenharmony_ci * same object with the input sptr object. 774e9297d28Sopenharmony_ci * @note This sptr will interpret the managed object as a type T. 775e9297d28Sopenharmony_ci * @param other Another sptr object with different managed class type(O). 776e9297d28Sopenharmony_ci */ 777e9297d28Sopenharmony_ci template <typename O> 778e9297d28Sopenharmony_ci sptr<T> &operator=(const sptr<O> &other); 779e9297d28Sopenharmony_ci 780e9297d28Sopenharmony_ci /** 781e9297d28Sopenharmony_ci * @brief Equal-to operator between sptr and a raw pointer. 782e9297d28Sopenharmony_ci * 783e9297d28Sopenharmony_ci * @param other Input raw pointer. 784e9297d28Sopenharmony_ci * @return Return true if sptr point to the same object with input 785e9297d28Sopenharmony_ci * raw pointer. 786e9297d28Sopenharmony_ci */ 787e9297d28Sopenharmony_ci bool operator==(const T *other) const; 788e9297d28Sopenharmony_ci 789e9297d28Sopenharmony_ci /** 790e9297d28Sopenharmony_ci * @brief Not-equal-to operator between sptr and a raw pointer. 791e9297d28Sopenharmony_ci * 792e9297d28Sopenharmony_ci * @param other Input raw pointer. 793e9297d28Sopenharmony_ci * @return Return true if sptr does not point to the same object with input 794e9297d28Sopenharmony_ci * raw pointer. 795e9297d28Sopenharmony_ci */ 796e9297d28Sopenharmony_ci inline bool operator!=(const T *other) const 797e9297d28Sopenharmony_ci { 798e9297d28Sopenharmony_ci return !operator==(other); 799e9297d28Sopenharmony_ci } 800e9297d28Sopenharmony_ci 801e9297d28Sopenharmony_ci /** 802e9297d28Sopenharmony_ci * @brief Equal-to operator between sptr and a wptr. 803e9297d28Sopenharmony_ci * 804e9297d28Sopenharmony_ci * @param other Input wptr. 805e9297d28Sopenharmony_ci * @return Return true if sptr and wptr are managing same object. 806e9297d28Sopenharmony_ci */ 807e9297d28Sopenharmony_ci bool operator==(const wptr<T> &other) const; 808e9297d28Sopenharmony_ci 809e9297d28Sopenharmony_ci /** 810e9297d28Sopenharmony_ci * @brief Not-equal-to operator between sptr and a wptr. 811e9297d28Sopenharmony_ci * 812e9297d28Sopenharmony_ci * @param other Input wptr. 813e9297d28Sopenharmony_ci * @return Return true if sptr and wptr are not managing same object. 814e9297d28Sopenharmony_ci */ 815e9297d28Sopenharmony_ci inline bool operator!=(const wptr<T> &other) const 816e9297d28Sopenharmony_ci { 817e9297d28Sopenharmony_ci return !operator==(other); 818e9297d28Sopenharmony_ci } 819e9297d28Sopenharmony_ci 820e9297d28Sopenharmony_ci /** 821e9297d28Sopenharmony_ci * @brief Equal-to operator between sptrs. 822e9297d28Sopenharmony_ci * 823e9297d28Sopenharmony_ci * @param other Input sptr. 824e9297d28Sopenharmony_ci * @return Return true if two sptrs are managing same object. 825e9297d28Sopenharmony_ci */ 826e9297d28Sopenharmony_ci bool operator==(const sptr<T> &other) const; 827e9297d28Sopenharmony_ci 828e9297d28Sopenharmony_ci /** 829e9297d28Sopenharmony_ci * @brief Not-equal-to operator between sptrs. 830e9297d28Sopenharmony_ci * 831e9297d28Sopenharmony_ci * @param other Input sptr. 832e9297d28Sopenharmony_ci * @return Return true if two sptrs are not managing same object. 833e9297d28Sopenharmony_ci */ 834e9297d28Sopenharmony_ci inline bool operator!=(const sptr<T> &other) const 835e9297d28Sopenharmony_ci { 836e9297d28Sopenharmony_ci return !operator==(other); 837e9297d28Sopenharmony_ci } 838e9297d28Sopenharmony_ci 839e9297d28Sopenharmony_ciprivate: 840e9297d28Sopenharmony_ci T *refs_ = nullptr; // Raw pointer to the managed specific object 841e9297d28Sopenharmony_ci}; 842e9297d28Sopenharmony_ci 843e9297d28Sopenharmony_citemplate <typename T> 844e9297d28Sopenharmony_ciinline void sptr<T>::ForceSetRefPtr(T *other) 845e9297d28Sopenharmony_ci{ 846e9297d28Sopenharmony_ci refs_ = other; 847e9297d28Sopenharmony_ci} 848e9297d28Sopenharmony_ci 849e9297d28Sopenharmony_citemplate <typename T> 850e9297d28Sopenharmony_ciinline sptr<T>::sptr() 851e9297d28Sopenharmony_ci{ 852e9297d28Sopenharmony_ci refs_ = nullptr; 853e9297d28Sopenharmony_ci} 854e9297d28Sopenharmony_ci 855e9297d28Sopenharmony_citemplate <typename T> 856e9297d28Sopenharmony_ciinline sptr<T>::sptr(T *other) 857e9297d28Sopenharmony_ci{ 858e9297d28Sopenharmony_ci refs_ = other; 859e9297d28Sopenharmony_ci if (refs_ != nullptr) { 860e9297d28Sopenharmony_ci refs_->IncStrongRef(this); 861e9297d28Sopenharmony_ci } 862e9297d28Sopenharmony_ci} 863e9297d28Sopenharmony_ci 864e9297d28Sopenharmony_citemplate <typename T> 865e9297d28Sopenharmony_ciinline sptr<T>::sptr(const sptr<T> &other) 866e9297d28Sopenharmony_ci{ 867e9297d28Sopenharmony_ci refs_ = other.GetRefPtr(); 868e9297d28Sopenharmony_ci if (refs_ != nullptr) { 869e9297d28Sopenharmony_ci refs_->IncStrongRef(this); 870e9297d28Sopenharmony_ci } 871e9297d28Sopenharmony_ci} 872e9297d28Sopenharmony_ci 873e9297d28Sopenharmony_citemplate <typename T> 874e9297d28Sopenharmony_cisptr<T>::sptr(sptr<T> &&other) 875e9297d28Sopenharmony_ci{ 876e9297d28Sopenharmony_ci refs_ = other.GetRefPtr(); 877e9297d28Sopenharmony_ci other.ForceSetRefPtr(nullptr); 878e9297d28Sopenharmony_ci} 879e9297d28Sopenharmony_ci 880e9297d28Sopenharmony_citemplate <typename T> 881e9297d28Sopenharmony_cisptr<T> &sptr<T>::operator=(sptr<T> &&other) 882e9297d28Sopenharmony_ci{ 883e9297d28Sopenharmony_ci if (refs_ != nullptr) { 884e9297d28Sopenharmony_ci refs_->DecStrongRef(this); 885e9297d28Sopenharmony_ci } 886e9297d28Sopenharmony_ci refs_ = other.GetRefPtr(); 887e9297d28Sopenharmony_ci other.ForceSetRefPtr(nullptr); 888e9297d28Sopenharmony_ci return *this; 889e9297d28Sopenharmony_ci} 890e9297d28Sopenharmony_ci 891e9297d28Sopenharmony_citemplate <typename T> 892e9297d28Sopenharmony_citemplate <typename O> 893e9297d28Sopenharmony_cisptr<T>::sptr(const sptr<O> &other) : refs_(other.GetRefPtr()) 894e9297d28Sopenharmony_ci{ 895e9297d28Sopenharmony_ci if (refs_ != nullptr) { 896e9297d28Sopenharmony_ci refs_->IncStrongRef(this); 897e9297d28Sopenharmony_ci } 898e9297d28Sopenharmony_ci} 899e9297d28Sopenharmony_ci 900e9297d28Sopenharmony_citemplate <typename T> 901e9297d28Sopenharmony_ciinline sptr<T> &sptr<T>::operator=(T *other) 902e9297d28Sopenharmony_ci{ 903e9297d28Sopenharmony_ci if (other != nullptr) { 904e9297d28Sopenharmony_ci other->IncStrongRef(this); 905e9297d28Sopenharmony_ci } 906e9297d28Sopenharmony_ci 907e9297d28Sopenharmony_ci if (refs_ != nullptr) { 908e9297d28Sopenharmony_ci refs_->DecStrongRef(this); 909e9297d28Sopenharmony_ci } 910e9297d28Sopenharmony_ci 911e9297d28Sopenharmony_ci refs_ = other; 912e9297d28Sopenharmony_ci return *this; 913e9297d28Sopenharmony_ci} 914e9297d28Sopenharmony_ci 915e9297d28Sopenharmony_citemplate <typename T> 916e9297d28Sopenharmony_ciinline sptr<T> &sptr<T>::operator=(const sptr<T> &other) 917e9297d28Sopenharmony_ci{ 918e9297d28Sopenharmony_ci T *otherRef(other.GetRefPtr()); 919e9297d28Sopenharmony_ci if (otherRef != nullptr) { 920e9297d28Sopenharmony_ci otherRef->IncStrongRef(this); 921e9297d28Sopenharmony_ci } 922e9297d28Sopenharmony_ci 923e9297d28Sopenharmony_ci if (refs_ != nullptr) { 924e9297d28Sopenharmony_ci refs_->DecStrongRef(this); 925e9297d28Sopenharmony_ci } 926e9297d28Sopenharmony_ci 927e9297d28Sopenharmony_ci refs_ = otherRef; 928e9297d28Sopenharmony_ci return *this; 929e9297d28Sopenharmony_ci} 930e9297d28Sopenharmony_ci 931e9297d28Sopenharmony_citemplate <typename T> 932e9297d28Sopenharmony_ciinline sptr<T> &sptr<T>::operator=(const wptr<T> &other) 933e9297d28Sopenharmony_ci{ 934e9297d28Sopenharmony_ci if (refs_ != nullptr) { 935e9297d28Sopenharmony_ci refs_->DecStrongRef(this); 936e9297d28Sopenharmony_ci } 937e9297d28Sopenharmony_ci if ((other != nullptr) && other.AttemptIncStrongRef(this)) { 938e9297d28Sopenharmony_ci refs_ = other.GetRefPtr(); 939e9297d28Sopenharmony_ci } else { 940e9297d28Sopenharmony_ci refs_ = nullptr; 941e9297d28Sopenharmony_ci } 942e9297d28Sopenharmony_ci 943e9297d28Sopenharmony_ci return *this; 944e9297d28Sopenharmony_ci} 945e9297d28Sopenharmony_ci 946e9297d28Sopenharmony_citemplate <typename T> 947e9297d28Sopenharmony_citemplate <typename O> 948e9297d28Sopenharmony_cisptr<T> &sptr<T>::operator=(const sptr<O> &other) 949e9297d28Sopenharmony_ci{ 950e9297d28Sopenharmony_ci T *otherRef(other.GetRefPtr()); 951e9297d28Sopenharmony_ci if (otherRef != nullptr) { 952e9297d28Sopenharmony_ci otherRef->IncStrongRef(this); 953e9297d28Sopenharmony_ci } 954e9297d28Sopenharmony_ci 955e9297d28Sopenharmony_ci if (refs_ != nullptr) { 956e9297d28Sopenharmony_ci refs_->DecStrongRef(this); 957e9297d28Sopenharmony_ci } 958e9297d28Sopenharmony_ci 959e9297d28Sopenharmony_ci refs_ = otherRef; 960e9297d28Sopenharmony_ci return *this; 961e9297d28Sopenharmony_ci} 962e9297d28Sopenharmony_ci 963e9297d28Sopenharmony_citemplate <typename T> 964e9297d28Sopenharmony_ciinline bool sptr<T>::operator==(const T *other) const 965e9297d28Sopenharmony_ci{ 966e9297d28Sopenharmony_ci return other == refs_; 967e9297d28Sopenharmony_ci} 968e9297d28Sopenharmony_ci 969e9297d28Sopenharmony_citemplate <typename T> 970e9297d28Sopenharmony_ciinline bool sptr<T>::operator==(const wptr<T> &other) const 971e9297d28Sopenharmony_ci{ 972e9297d28Sopenharmony_ci return refs_ == other.GetRefPtr(); 973e9297d28Sopenharmony_ci} 974e9297d28Sopenharmony_ci 975e9297d28Sopenharmony_citemplate <typename T> 976e9297d28Sopenharmony_ciinline bool sptr<T>::operator==(const sptr<T> &other) const 977e9297d28Sopenharmony_ci{ 978e9297d28Sopenharmony_ci return refs_ == other.GetRefPtr(); 979e9297d28Sopenharmony_ci} 980e9297d28Sopenharmony_ci 981e9297d28Sopenharmony_citemplate<typename T> 982e9297d28Sopenharmony_civoid sptr<T>::clear() 983e9297d28Sopenharmony_ci{ 984e9297d28Sopenharmony_ci if (refs_) { 985e9297d28Sopenharmony_ci refs_->DecStrongRef(this); 986e9297d28Sopenharmony_ci refs_ = 0; 987e9297d28Sopenharmony_ci } 988e9297d28Sopenharmony_ci} 989e9297d28Sopenharmony_ci 990e9297d28Sopenharmony_citemplate <typename T> 991e9297d28Sopenharmony_ciinline sptr<T>::~sptr() 992e9297d28Sopenharmony_ci{ 993e9297d28Sopenharmony_ci if (refs_ != nullptr) { 994e9297d28Sopenharmony_ci refs_->DecStrongRef(this); 995e9297d28Sopenharmony_ci } 996e9297d28Sopenharmony_ci} 997e9297d28Sopenharmony_ci 998e9297d28Sopenharmony_citemplate <typename T> 999e9297d28Sopenharmony_ciinline sptr<T>::sptr(WeakRefCounter *p, bool /* force */) 1000e9297d28Sopenharmony_ci{ 1001e9297d28Sopenharmony_ci if ((p != nullptr) && p->AttemptIncStrongRef(this)) { 1002e9297d28Sopenharmony_ci refs_ = reinterpret_cast<T *>(p->GetRefPtr()); 1003e9297d28Sopenharmony_ci } else { 1004e9297d28Sopenharmony_ci refs_ = nullptr; 1005e9297d28Sopenharmony_ci } 1006e9297d28Sopenharmony_ci} 1007e9297d28Sopenharmony_ci 1008e9297d28Sopenharmony_ci/** 1009e9297d28Sopenharmony_ci * @ingroup SmartPointer 1010e9297d28Sopenharmony_ci * @brief Weak reference smart pointer to a RefBase(or its subclass) object. 1011e9297d28Sopenharmony_ci * 1012e9297d28Sopenharmony_ci * Indirectly reference the RefBase object; 1013e9297d28Sopenharmony_ci * Directly reference the WeakRefCounter object. 1014e9297d28Sopenharmony_ci * 1015e9297d28Sopenharmony_ci * @tparam T Specific class type managed by wptr. 1016e9297d28Sopenharmony_ci * This class must inherit from RefBase. 1017e9297d28Sopenharmony_ci */ 1018e9297d28Sopenharmony_citemplate <typename T> 1019e9297d28Sopenharmony_ciclass wptr { 1020e9297d28Sopenharmony_ci template <typename O> 1021e9297d28Sopenharmony_ci friend class wptr; 1022e9297d28Sopenharmony_ci 1023e9297d28Sopenharmony_cipublic: 1024e9297d28Sopenharmony_ci wptr(); 1025e9297d28Sopenharmony_ci 1026e9297d28Sopenharmony_ci /** 1027e9297d28Sopenharmony_ci * @brief Constructor with specified object to be managed. 1028e9297d28Sopenharmony_ci * 1029e9297d28Sopenharmony_ci * This method will create WeakRefCounter object for `other` and set its 1030e9297d28Sopenharmony_ci * weak reference count to 1. 1031e9297d28Sopenharmony_ci * 1032e9297d28Sopenharmony_ci * @note WeakRefCounter object will not be created if `other` is a 1033e9297d28Sopenharmony_ci * `nullptr`. 1034e9297d28Sopenharmony_ci * @param other Object to be managed by wptr. 1035e9297d28Sopenharmony_ci */ 1036e9297d28Sopenharmony_ci wptr(T *other); 1037e9297d28Sopenharmony_ci 1038e9297d28Sopenharmony_ci /** 1039e9297d28Sopenharmony_ci * @brief Copy constructor for wptr with same managed class type(T). 1040e9297d28Sopenharmony_ci * 1041e9297d28Sopenharmony_ci * This method will share the WeakRefCounter object of `other` with this 1042e9297d28Sopenharmony_ci * wptr. Weak reference count in this WeakRefCounter object will be set 1043e9297d28Sopenharmony_ci * properly. 1044e9297d28Sopenharmony_ci * 1045e9297d28Sopenharmony_ci * @param other Another wptr with same managed class type(T). 1046e9297d28Sopenharmony_ci */ 1047e9297d28Sopenharmony_ci wptr(const wptr<T> &other); 1048e9297d28Sopenharmony_ci 1049e9297d28Sopenharmony_ci /** 1050e9297d28Sopenharmony_ci * @brief Copy constructor for sptr with same managed class type(T). 1051e9297d28Sopenharmony_ci * 1052e9297d28Sopenharmony_ci * This method will create WeakRefCounter object for the managed object of 1053e9297d28Sopenharmony_ci * `other`, and set its weak reference count properly. 1054e9297d28Sopenharmony_ci * 1055e9297d28Sopenharmony_ci * @param other Another sptr with same managed class type(T). 1056e9297d28Sopenharmony_ci * @tparam T Specific class type managed by `other`. 1057e9297d28Sopenharmony_ci */ 1058e9297d28Sopenharmony_ci wptr(const sptr<T> &other); 1059e9297d28Sopenharmony_ci 1060e9297d28Sopenharmony_ci /** 1061e9297d28Sopenharmony_ci * @brief Copy constructor for wptr with different managed class type(O). 1062e9297d28Sopenharmony_ci * 1063e9297d28Sopenharmony_ci * Same with wptr<T>::wptr(const wptr<T> &other). 1064e9297d28Sopenharmony_ci * 1065e9297d28Sopenharmony_ci * @tparam O Class type managed by `other`. 1066e9297d28Sopenharmony_ci * @param other Another wptr with different managed class type(O). 1067e9297d28Sopenharmony_ci * @tparam T Specific class type managed by `other`. 1068e9297d28Sopenharmony_ci */ 1069e9297d28Sopenharmony_ci template <typename O> 1070e9297d28Sopenharmony_ci wptr(const wptr<O> &other); 1071e9297d28Sopenharmony_ci 1072e9297d28Sopenharmony_ci /** 1073e9297d28Sopenharmony_ci * @brief Copy constructor for sptr with different managed class type(O). 1074e9297d28Sopenharmony_ci * 1075e9297d28Sopenharmony_ci * Same with wptr<T>::wptr(const sptr<T> &other). 1076e9297d28Sopenharmony_ci * 1077e9297d28Sopenharmony_ci * @param other Another sptr with same managed class type(O). 1078e9297d28Sopenharmony_ci * @tparam T Specific class type managed by `other`. 1079e9297d28Sopenharmony_ci */ 1080e9297d28Sopenharmony_ci template <typename O> 1081e9297d28Sopenharmony_ci wptr(const sptr<O> &other); 1082e9297d28Sopenharmony_ci 1083e9297d28Sopenharmony_ci /** 1084e9297d28Sopenharmony_ci * @brief Copy assignment operator with specified object to be managed. 1085e9297d28Sopenharmony_ci * 1086e9297d28Sopenharmony_ci * @note Current wptr will unbind the original WeakRefCounter object and 1087e9297d28Sopenharmony_ci * create a new WeakRefCounter object, then set its weak reference count 1088e9297d28Sopenharmony_ci * properly. 1089e9297d28Sopenharmony_ci * @param other Another object to be managed by this wptr. 1090e9297d28Sopenharmony_ci */ 1091e9297d28Sopenharmony_ci wptr<T> &operator=(T *other); 1092e9297d28Sopenharmony_ci 1093e9297d28Sopenharmony_ci /** 1094e9297d28Sopenharmony_ci * @brief Copy assignment operator with specified object to be managed. 1095e9297d28Sopenharmony_ci * 1096e9297d28Sopenharmony_ci * @note Same with wptr<T> &operator=(T *other), but a pointer type casting 1097e9297d28Sopenharmony_ci * which will not affect the type of `*other` is proccessed. 1098e9297d28Sopenharmony_ci * @tparam O Specific class type managed by `other`. 1099e9297d28Sopenharmony_ci * @param other Another object to be managed by this wptr. 1100e9297d28Sopenharmony_ci * 1101e9297d28Sopenharmony_ci */ 1102e9297d28Sopenharmony_ci template <typename O> 1103e9297d28Sopenharmony_ci wptr<T> &operator=(O *other); 1104e9297d28Sopenharmony_ci 1105e9297d28Sopenharmony_ci /** 1106e9297d28Sopenharmony_ci * @brief Copy assignment operator for wptr with same managed class type(T). 1107e9297d28Sopenharmony_ci * 1108e9297d28Sopenharmony_ci * @note Current wptr will unbind the original WeakRefCounter object and 1109e9297d28Sopenharmony_ci * share the WeakRefCounter object with `other`, then set its weak 1110e9297d28Sopenharmony_ci * reference count properly. 1111e9297d28Sopenharmony_ci * @param other Another wptr. Object managed by it will also be managed by 1112e9297d28Sopenharmony_ci * this wptr. 1113e9297d28Sopenharmony_ci */ 1114e9297d28Sopenharmony_ci wptr<T> &operator=(const wptr<T> &other); 1115e9297d28Sopenharmony_ci 1116e9297d28Sopenharmony_ci /** 1117e9297d28Sopenharmony_ci * @brief Copy assignment operator for sptr with 1118e9297d28Sopenharmony_ci * same managed class type(T). 1119e9297d28Sopenharmony_ci * 1120e9297d28Sopenharmony_ci * @note Current wptr will unbind the original WeakRefCounter object and 1121e9297d28Sopenharmony_ci * create a new WeakRefCounter object, then set its weak reference count 1122e9297d28Sopenharmony_ci * properly. 1123e9297d28Sopenharmony_ci * @param other A sptr object. Object managed by it will also be managed by 1124e9297d28Sopenharmony_ci * this wptr. 1125e9297d28Sopenharmony_ci */ 1126e9297d28Sopenharmony_ci wptr<T> &operator=(const sptr<T> &other); 1127e9297d28Sopenharmony_ci 1128e9297d28Sopenharmony_ci /** 1129e9297d28Sopenharmony_ci * @brief Copy assignment operator for wptr with 1130e9297d28Sopenharmony_ci * different managed class type(O). 1131e9297d28Sopenharmony_ci * 1132e9297d28Sopenharmony_ci * @note Same with wptr<T> &operator=(const wptr<T> &). Note that no cast 1133e9297d28Sopenharmony_ci * here is proccessed. 1134e9297d28Sopenharmony_ci * @param other An wptr object. Object managed by it will also be managed by 1135e9297d28Sopenharmony_ci * this wptr. 1136e9297d28Sopenharmony_ci * @tparam O Specific class type managed by `other`. 1137e9297d28Sopenharmony_ci */ 1138e9297d28Sopenharmony_ci template <typename O> 1139e9297d28Sopenharmony_ci wptr<T> &operator=(const wptr<O> &other); 1140e9297d28Sopenharmony_ci 1141e9297d28Sopenharmony_ci /** 1142e9297d28Sopenharmony_ci * @brief Copy assignment operator for sptr with 1143e9297d28Sopenharmony_ci * different managed class type(O). 1144e9297d28Sopenharmony_ci * 1145e9297d28Sopenharmony_ci * @note Same with wptr<T> &wptr<T>::operator=(const sptr<T> &). Note that 1146e9297d28Sopenharmony_ci * no cast here is proccessed. 1147e9297d28Sopenharmony_ci * @param other An sptr object. Object managed by it will also be managed by 1148e9297d28Sopenharmony_ci * this wptr. 1149e9297d28Sopenharmony_ci * @tparam O Specific class type managed by `other`. 1150e9297d28Sopenharmony_ci */ 1151e9297d28Sopenharmony_ci template <typename O> 1152e9297d28Sopenharmony_ci wptr<T> &operator=(const sptr<O> &other); 1153e9297d28Sopenharmony_ci 1154e9297d28Sopenharmony_ci /** 1155e9297d28Sopenharmony_ci * @brief Dereference operator. It will return the object managed by this 1156e9297d28Sopenharmony_ci * wptr. 1157e9297d28Sopenharmony_ci * 1158e9297d28Sopenharmony_ci * @return Return specific object managed by wptr. 1159e9297d28Sopenharmony_ci */ 1160e9297d28Sopenharmony_ci inline T &operator*() const 1161e9297d28Sopenharmony_ci { 1162e9297d28Sopenharmony_ci return *GetRefPtr(); 1163e9297d28Sopenharmony_ci } 1164e9297d28Sopenharmony_ci 1165e9297d28Sopenharmony_ci /** 1166e9297d28Sopenharmony_ci * @brief Member selection operator. 1167e9297d28Sopenharmony_ci * 1168e9297d28Sopenharmony_ci * It will return the specified member of the object managed by this wptr. 1169e9297d28Sopenharmony_ci */ 1170e9297d28Sopenharmony_ci inline T *operator->() const 1171e9297d28Sopenharmony_ci { 1172e9297d28Sopenharmony_ci return reinterpret_cast<T *>(refs_->GetRefPtr()); 1173e9297d28Sopenharmony_ci } 1174e9297d28Sopenharmony_ci 1175e9297d28Sopenharmony_ci /** 1176e9297d28Sopenharmony_ci * @brief Equal-to operator between wptr and a raw pointer. 1177e9297d28Sopenharmony_ci * 1178e9297d28Sopenharmony_ci * @param other Input raw pointer. 1179e9297d28Sopenharmony_ci * @return Return true if two pointers have same value. 1180e9297d28Sopenharmony_ci */ 1181e9297d28Sopenharmony_ci bool operator==(const T *other) const; 1182e9297d28Sopenharmony_ci 1183e9297d28Sopenharmony_ci /** 1184e9297d28Sopenharmony_ci * @brief Not-equal-to operator between wptr and a raw pointer. 1185e9297d28Sopenharmony_ci * 1186e9297d28Sopenharmony_ci * @param other Input raw pointer. 1187e9297d28Sopenharmony_ci * @return Return true if two pointers have different value. 1188e9297d28Sopenharmony_ci */ 1189e9297d28Sopenharmony_ci inline bool operator!=(const T *other) const 1190e9297d28Sopenharmony_ci { 1191e9297d28Sopenharmony_ci return !operator==(other); 1192e9297d28Sopenharmony_ci }; 1193e9297d28Sopenharmony_ci 1194e9297d28Sopenharmony_ci /** 1195e9297d28Sopenharmony_ci * @brief Equal-to operator between two wptrs. 1196e9297d28Sopenharmony_ci * 1197e9297d28Sopenharmony_ci * @param other Input reference of a wptr object. 1198e9297d28Sopenharmony_ci * @return Return if two pointers have same value. 1199e9297d28Sopenharmony_ci */ 1200e9297d28Sopenharmony_ci bool operator==(const wptr<T> &other) const; 1201e9297d28Sopenharmony_ci 1202e9297d28Sopenharmony_ci /** 1203e9297d28Sopenharmony_ci * @brief Not-equal-to operator between two wptrs. 1204e9297d28Sopenharmony_ci * 1205e9297d28Sopenharmony_ci * @param other Input reference of a wptr object. 1206e9297d28Sopenharmony_ci * @return Return if two pointers have different value. 1207e9297d28Sopenharmony_ci */ 1208e9297d28Sopenharmony_ci inline bool operator!=(const wptr<T> &other) const 1209e9297d28Sopenharmony_ci { 1210e9297d28Sopenharmony_ci return !operator==(other); 1211e9297d28Sopenharmony_ci } 1212e9297d28Sopenharmony_ci 1213e9297d28Sopenharmony_ci /** 1214e9297d28Sopenharmony_ci * @brief Equal-to operator between wptr and a input sptr object. 1215e9297d28Sopenharmony_ci * 1216e9297d28Sopenharmony_ci * @param other Input reference of an sptr object. 1217e9297d28Sopenharmony_ci * @return Comparison result. 1218e9297d28Sopenharmony_ci */ 1219e9297d28Sopenharmony_ci bool operator==(const sptr<T> &other) const; 1220e9297d28Sopenharmony_ci 1221e9297d28Sopenharmony_ci /** 1222e9297d28Sopenharmony_ci * @brief Not-Equal-to operator between wptr and a input sptr object. 1223e9297d28Sopenharmony_ci * 1224e9297d28Sopenharmony_ci * @param other Input reference of an sptr object. 1225e9297d28Sopenharmony_ci * @return Comparison result. 1226e9297d28Sopenharmony_ci */ 1227e9297d28Sopenharmony_ci inline bool operator!=(const sptr<T> &other) const 1228e9297d28Sopenharmony_ci { 1229e9297d28Sopenharmony_ci return !operator==(other); 1230e9297d28Sopenharmony_ci } 1231e9297d28Sopenharmony_ci 1232e9297d28Sopenharmony_ci /** 1233e9297d28Sopenharmony_ci * @brief Get the pointer to the RefBase object. 1234e9297d28Sopenharmony_ci * 1235e9297d28Sopenharmony_ci * @return Raw pointer to the RefBase object. 1236e9297d28Sopenharmony_ci * @note Return `nullptr` if the managed object has been deallocated. 1237e9297d28Sopenharmony_ci */ 1238e9297d28Sopenharmony_ci T *GetRefPtr() const; 1239e9297d28Sopenharmony_ci 1240e9297d28Sopenharmony_ci /** 1241e9297d28Sopenharmony_ci * @brief Get the count value of corresponding WeakRefCounter object. 1242e9297d28Sopenharmony_ci * 1243e9297d28Sopenharmony_ci * The value indicates how many wptrs share the same WeakRefCounter object. 1244e9297d28Sopenharmony_ci * 1245e9297d28Sopenharmony_ci * @return Value of the count. 1246e9297d28Sopenharmony_ci * @note Only for test. 1247e9297d28Sopenharmony_ci */ 1248e9297d28Sopenharmony_ci inline int GetWeakRefCount() const 1249e9297d28Sopenharmony_ci { 1250e9297d28Sopenharmony_ci return refs_->GetWeakRefCount(); 1251e9297d28Sopenharmony_ci } 1252e9297d28Sopenharmony_ci 1253e9297d28Sopenharmony_ci /** 1254e9297d28Sopenharmony_ci * @brief Attempt to increment the strong reference count of 1255e9297d28Sopenharmony_ci * the managed object. 1256e9297d28Sopenharmony_ci * 1257e9297d28Sopenharmony_ci * @return Return true after a success increment. 1258e9297d28Sopenharmony_ci * @note Avoid using it independently. Use `promote()`. 1259e9297d28Sopenharmony_ci */ 1260e9297d28Sopenharmony_ci inline bool AttemptIncStrongRef(const void *objectId) const 1261e9297d28Sopenharmony_ci { 1262e9297d28Sopenharmony_ci return refs_->AttemptIncStrongRef(objectId); 1263e9297d28Sopenharmony_ci } 1264e9297d28Sopenharmony_ci 1265e9297d28Sopenharmony_ci /** 1266e9297d28Sopenharmony_ci * @brief Promote a wptr to an sptr. 1267e9297d28Sopenharmony_ci * 1268e9297d28Sopenharmony_ci * It will create an sptr object based on 1269e9297d28Sopenharmony_ci * object managed by this wptr. 1270e9297d28Sopenharmony_ci * 1271e9297d28Sopenharmony_ci * @note Original weak reference will be retained. Promote may fail, 1272e9297d28Sopenharmony_ci * and then return a "null sptr". 1273e9297d28Sopenharmony_ci */ 1274e9297d28Sopenharmony_ci const sptr<T> promote() const; 1275e9297d28Sopenharmony_ci 1276e9297d28Sopenharmony_ci ~wptr(); 1277e9297d28Sopenharmony_ci 1278e9297d28Sopenharmony_ciprivate: 1279e9297d28Sopenharmony_ci WeakRefCounter *refs_ = nullptr; // Pointer to the corresponding weak reference counter object 1280e9297d28Sopenharmony_ci}; 1281e9297d28Sopenharmony_ci 1282e9297d28Sopenharmony_citemplate <typename T> 1283e9297d28Sopenharmony_ciinline T *wptr<T>::GetRefPtr() const 1284e9297d28Sopenharmony_ci{ 1285e9297d28Sopenharmony_ci return (refs_ != nullptr) ? reinterpret_cast<T *>(refs_->GetRefPtr()) : nullptr; 1286e9297d28Sopenharmony_ci} 1287e9297d28Sopenharmony_ci 1288e9297d28Sopenharmony_citemplate <typename T> 1289e9297d28Sopenharmony_ciwptr<T>::wptr() 1290e9297d28Sopenharmony_ci{ 1291e9297d28Sopenharmony_ci refs_ = nullptr; 1292e9297d28Sopenharmony_ci} 1293e9297d28Sopenharmony_ci 1294e9297d28Sopenharmony_citemplate <typename T> 1295e9297d28Sopenharmony_ciwptr<T>::wptr(T *other) 1296e9297d28Sopenharmony_ci{ 1297e9297d28Sopenharmony_ci if (other != nullptr) { 1298e9297d28Sopenharmony_ci refs_ = other->CreateWeakRef(other); 1299e9297d28Sopenharmony_ci if (refs_ != nullptr) { 1300e9297d28Sopenharmony_ci refs_->IncWeakRefCount(this); 1301e9297d28Sopenharmony_ci } 1302e9297d28Sopenharmony_ci } else { 1303e9297d28Sopenharmony_ci refs_ = nullptr; 1304e9297d28Sopenharmony_ci } 1305e9297d28Sopenharmony_ci} 1306e9297d28Sopenharmony_ci 1307e9297d28Sopenharmony_citemplate <typename T> 1308e9297d28Sopenharmony_ciwptr<T>::wptr(const wptr<T> &other) 1309e9297d28Sopenharmony_ci{ 1310e9297d28Sopenharmony_ci refs_ = other.refs_; 1311e9297d28Sopenharmony_ci if (refs_ != nullptr) { 1312e9297d28Sopenharmony_ci refs_->IncWeakRefCount(this); 1313e9297d28Sopenharmony_ci } 1314e9297d28Sopenharmony_ci} 1315e9297d28Sopenharmony_ci 1316e9297d28Sopenharmony_citemplate <typename T> 1317e9297d28Sopenharmony_ciwptr<T>::wptr(const sptr<T> &other) 1318e9297d28Sopenharmony_ci{ 1319e9297d28Sopenharmony_ci if (other.GetRefPtr() != nullptr) { 1320e9297d28Sopenharmony_ci refs_ = other->CreateWeakRef(other.GetRefPtr()); 1321e9297d28Sopenharmony_ci if (refs_ != nullptr) { 1322e9297d28Sopenharmony_ci refs_->IncWeakRefCount(this); 1323e9297d28Sopenharmony_ci } 1324e9297d28Sopenharmony_ci } 1325e9297d28Sopenharmony_ci} 1326e9297d28Sopenharmony_ci 1327e9297d28Sopenharmony_citemplate <typename T> 1328e9297d28Sopenharmony_citemplate <typename O> 1329e9297d28Sopenharmony_ciwptr<T>::wptr(const wptr<O> &other) 1330e9297d28Sopenharmony_ci{ 1331e9297d28Sopenharmony_ci refs_ = other.refs_; 1332e9297d28Sopenharmony_ci if (refs_ != nullptr) { 1333e9297d28Sopenharmony_ci refs_->IncWeakRefCount(this); 1334e9297d28Sopenharmony_ci } 1335e9297d28Sopenharmony_ci} 1336e9297d28Sopenharmony_ci 1337e9297d28Sopenharmony_citemplate <typename T> 1338e9297d28Sopenharmony_citemplate <typename O> 1339e9297d28Sopenharmony_ciwptr<T>::wptr(const sptr<O> &other) 1340e9297d28Sopenharmony_ci{ 1341e9297d28Sopenharmony_ci if (other.GetRefPtr() != nullptr) { 1342e9297d28Sopenharmony_ci refs_ = other->CreateWeakRef(other.GetRefPtr()); 1343e9297d28Sopenharmony_ci if (refs_ != nullptr) { 1344e9297d28Sopenharmony_ci refs_->IncWeakRefCount(this); 1345e9297d28Sopenharmony_ci } 1346e9297d28Sopenharmony_ci } 1347e9297d28Sopenharmony_ci} 1348e9297d28Sopenharmony_ci 1349e9297d28Sopenharmony_citemplate <typename T> 1350e9297d28Sopenharmony_ciwptr<T> &wptr<T>::operator=(T *other) 1351e9297d28Sopenharmony_ci{ 1352e9297d28Sopenharmony_ci WeakRefCounter *newWeakRef = nullptr; 1353e9297d28Sopenharmony_ci if (other != nullptr) { 1354e9297d28Sopenharmony_ci newWeakRef = other->CreateWeakRef(other); 1355e9297d28Sopenharmony_ci if (newWeakRef != nullptr) { 1356e9297d28Sopenharmony_ci newWeakRef->IncWeakRefCount(this); 1357e9297d28Sopenharmony_ci } 1358e9297d28Sopenharmony_ci } 1359e9297d28Sopenharmony_ci 1360e9297d28Sopenharmony_ci if (refs_ != nullptr) { 1361e9297d28Sopenharmony_ci refs_->DecWeakRefCount(this); 1362e9297d28Sopenharmony_ci } 1363e9297d28Sopenharmony_ci 1364e9297d28Sopenharmony_ci refs_ = newWeakRef; 1365e9297d28Sopenharmony_ci return *this; 1366e9297d28Sopenharmony_ci} 1367e9297d28Sopenharmony_ci 1368e9297d28Sopenharmony_citemplate <typename T> 1369e9297d28Sopenharmony_citemplate <typename O> 1370e9297d28Sopenharmony_ciwptr<T> &wptr<T>::operator=(O *other) 1371e9297d28Sopenharmony_ci{ 1372e9297d28Sopenharmony_ci T *object = reinterpret_cast<T *>(other); 1373e9297d28Sopenharmony_ci WeakRefCounter *newWeakRef = nullptr; 1374e9297d28Sopenharmony_ci if (object != nullptr) { 1375e9297d28Sopenharmony_ci newWeakRef = object->CreateWeakRef(object); 1376e9297d28Sopenharmony_ci if (newWeakRef != nullptr) { 1377e9297d28Sopenharmony_ci newWeakRef->IncWeakRefCount(this); 1378e9297d28Sopenharmony_ci } 1379e9297d28Sopenharmony_ci } 1380e9297d28Sopenharmony_ci 1381e9297d28Sopenharmony_ci if (refs_ != nullptr) { 1382e9297d28Sopenharmony_ci refs_->DecWeakRefCount(this); 1383e9297d28Sopenharmony_ci } 1384e9297d28Sopenharmony_ci 1385e9297d28Sopenharmony_ci refs_ = newWeakRef; 1386e9297d28Sopenharmony_ci return *this; 1387e9297d28Sopenharmony_ci} 1388e9297d28Sopenharmony_ci 1389e9297d28Sopenharmony_citemplate <typename T> 1390e9297d28Sopenharmony_ciinline wptr<T> &wptr<T>::operator=(const wptr<T> &other) 1391e9297d28Sopenharmony_ci{ 1392e9297d28Sopenharmony_ci if (other.refs_ != nullptr) { 1393e9297d28Sopenharmony_ci other.refs_->IncWeakRefCount(this); 1394e9297d28Sopenharmony_ci } 1395e9297d28Sopenharmony_ci 1396e9297d28Sopenharmony_ci if (refs_ != nullptr) { 1397e9297d28Sopenharmony_ci refs_->DecWeakRefCount(this); 1398e9297d28Sopenharmony_ci } 1399e9297d28Sopenharmony_ci 1400e9297d28Sopenharmony_ci refs_ = other.refs_; 1401e9297d28Sopenharmony_ci return *this; 1402e9297d28Sopenharmony_ci} 1403e9297d28Sopenharmony_ci 1404e9297d28Sopenharmony_citemplate <typename T> 1405e9297d28Sopenharmony_ciinline wptr<T> &wptr<T>::operator=(const sptr<T> &other) 1406e9297d28Sopenharmony_ci{ 1407e9297d28Sopenharmony_ci WeakRefCounter *newWeakRef = nullptr; 1408e9297d28Sopenharmony_ci if (other.GetRefPtr() != nullptr) { 1409e9297d28Sopenharmony_ci newWeakRef = other->CreateWeakRef(other.GetRefPtr()); 1410e9297d28Sopenharmony_ci if (newWeakRef != nullptr) { 1411e9297d28Sopenharmony_ci newWeakRef->IncWeakRefCount(this); 1412e9297d28Sopenharmony_ci } 1413e9297d28Sopenharmony_ci } 1414e9297d28Sopenharmony_ci 1415e9297d28Sopenharmony_ci if (refs_ != nullptr) { 1416e9297d28Sopenharmony_ci refs_->DecWeakRefCount(this); 1417e9297d28Sopenharmony_ci } 1418e9297d28Sopenharmony_ci 1419e9297d28Sopenharmony_ci refs_ = newWeakRef; 1420e9297d28Sopenharmony_ci return *this; 1421e9297d28Sopenharmony_ci} 1422e9297d28Sopenharmony_ci 1423e9297d28Sopenharmony_citemplate <typename T> 1424e9297d28Sopenharmony_citemplate <typename O> 1425e9297d28Sopenharmony_ciwptr<T> &wptr<T>::operator=(const wptr<O> &other) 1426e9297d28Sopenharmony_ci{ 1427e9297d28Sopenharmony_ci if (other.refs_ != nullptr) { 1428e9297d28Sopenharmony_ci other.refs_->IncWeakRefCount(this); 1429e9297d28Sopenharmony_ci } 1430e9297d28Sopenharmony_ci 1431e9297d28Sopenharmony_ci if (refs_ != nullptr) { 1432e9297d28Sopenharmony_ci refs_->DecWeakRefCount(this); 1433e9297d28Sopenharmony_ci } 1434e9297d28Sopenharmony_ci 1435e9297d28Sopenharmony_ci refs_ = other.refs_; 1436e9297d28Sopenharmony_ci return *this; 1437e9297d28Sopenharmony_ci} 1438e9297d28Sopenharmony_ci 1439e9297d28Sopenharmony_citemplate <typename T> 1440e9297d28Sopenharmony_citemplate <typename O> 1441e9297d28Sopenharmony_ciwptr<T> &wptr<T>::operator=(const sptr<O> &other) 1442e9297d28Sopenharmony_ci{ 1443e9297d28Sopenharmony_ci WeakRefCounter *newWeakRef = nullptr; 1444e9297d28Sopenharmony_ci if (other.GetRefPtr() != nullptr) { 1445e9297d28Sopenharmony_ci newWeakRef = other->CreateWeakRef(other.GetRefPtr()); 1446e9297d28Sopenharmony_ci if (newWeakRef != nullptr) { 1447e9297d28Sopenharmony_ci newWeakRef->IncWeakRefCount(this); 1448e9297d28Sopenharmony_ci } 1449e9297d28Sopenharmony_ci } 1450e9297d28Sopenharmony_ci 1451e9297d28Sopenharmony_ci if (refs_ != nullptr) { 1452e9297d28Sopenharmony_ci refs_->DecWeakRefCount(this); 1453e9297d28Sopenharmony_ci } 1454e9297d28Sopenharmony_ci 1455e9297d28Sopenharmony_ci refs_ = newWeakRef; 1456e9297d28Sopenharmony_ci return *this; 1457e9297d28Sopenharmony_ci} 1458e9297d28Sopenharmony_ci 1459e9297d28Sopenharmony_citemplate <typename T> 1460e9297d28Sopenharmony_ciinline bool wptr<T>::operator==(const T *other) const 1461e9297d28Sopenharmony_ci{ 1462e9297d28Sopenharmony_ci return GetRefPtr() == other; 1463e9297d28Sopenharmony_ci} 1464e9297d28Sopenharmony_ci 1465e9297d28Sopenharmony_citemplate <typename T> 1466e9297d28Sopenharmony_ciinline bool wptr<T>::operator==(const wptr<T> &other) const 1467e9297d28Sopenharmony_ci{ 1468e9297d28Sopenharmony_ci return GetRefPtr() == other.GetRefPtr(); 1469e9297d28Sopenharmony_ci} 1470e9297d28Sopenharmony_ci 1471e9297d28Sopenharmony_citemplate <typename T> 1472e9297d28Sopenharmony_ciinline bool wptr<T>::operator==(const sptr<T> &other) const 1473e9297d28Sopenharmony_ci{ 1474e9297d28Sopenharmony_ci return GetRefPtr() == other.GetRefPtr(); 1475e9297d28Sopenharmony_ci} 1476e9297d28Sopenharmony_ci 1477e9297d28Sopenharmony_citemplate <typename T> 1478e9297d28Sopenharmony_ciinline const sptr<T> wptr<T>::promote() const 1479e9297d28Sopenharmony_ci{ 1480e9297d28Sopenharmony_ci return sptr<T>(refs_, true); 1481e9297d28Sopenharmony_ci} 1482e9297d28Sopenharmony_ci 1483e9297d28Sopenharmony_citemplate <typename T> 1484e9297d28Sopenharmony_ciinline wptr<T>::~wptr() 1485e9297d28Sopenharmony_ci{ 1486e9297d28Sopenharmony_ci if (refs_ != nullptr) { 1487e9297d28Sopenharmony_ci refs_->DecWeakRefCount(this); 1488e9297d28Sopenharmony_ci } 1489e9297d28Sopenharmony_ci} 1490e9297d28Sopenharmony_ci 1491e9297d28Sopenharmony_ci} // namespace OHOS 1492e9297d28Sopenharmony_ci 1493e9297d28Sopenharmony_ci#endif 1494e9297d28Sopenharmony_ci 1495e9297d28Sopenharmony_ci/**@}*/ 1496