13f4cbf05Sopenharmony_ci/* 23f4cbf05Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 33f4cbf05Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43f4cbf05Sopenharmony_ci * you may not use this file except in compliance with the License. 53f4cbf05Sopenharmony_ci * You may obtain a copy of the License at 63f4cbf05Sopenharmony_ci * 73f4cbf05Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83f4cbf05Sopenharmony_ci * 93f4cbf05Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103f4cbf05Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113f4cbf05Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123f4cbf05Sopenharmony_ci * See the License for the specific language governing permissions and 133f4cbf05Sopenharmony_ci * limitations under the License. 143f4cbf05Sopenharmony_ci */ 153f4cbf05Sopenharmony_ci 163f4cbf05Sopenharmony_ci /** 173f4cbf05Sopenharmony_ci * @file refbase.h 183f4cbf05Sopenharmony_ci * 193f4cbf05Sopenharmony_ci * @brief Provide smart pointer implemented in c_utils. 203f4cbf05Sopenharmony_ci */ 213f4cbf05Sopenharmony_ci 223f4cbf05Sopenharmony_ci /** 233f4cbf05Sopenharmony_ci * @defgroup SmartPointer 243f4cbf05Sopenharmony_ci * @{ 253f4cbf05Sopenharmony_ci * @brief SmartPointer is a pointer-like class. 263f4cbf05Sopenharmony_ci * 273f4cbf05Sopenharmony_ci * This class simulates a pointer while providing 283f4cbf05Sopenharmony_ci * enhanced features, such as automatic memory management.\n 293f4cbf05Sopenharmony_ci * Automatic memory management helps to deallocate 303f4cbf05Sopenharmony_ci * memory resources correctly when an object's life time expires. 313f4cbf05Sopenharmony_ci */ 323f4cbf05Sopenharmony_ci 333f4cbf05Sopenharmony_ci#ifndef UTILS_BASE_REFBASE_H 343f4cbf05Sopenharmony_ci#define UTILS_BASE_REFBASE_H 353f4cbf05Sopenharmony_ci 363f4cbf05Sopenharmony_ci#include <atomic> 373f4cbf05Sopenharmony_ci#include <functional> 383f4cbf05Sopenharmony_ci#ifdef DEBUG_REFBASE 393f4cbf05Sopenharmony_ci#include <mutex> 403f4cbf05Sopenharmony_ci#endif 413f4cbf05Sopenharmony_ci 423f4cbf05Sopenharmony_cinamespace OHOS { 433f4cbf05Sopenharmony_ci/** 443f4cbf05Sopenharmony_ci * @ingroup SmartPointer 453f4cbf05Sopenharmony_ci * @brief A value indicates no strong references ever. 463f4cbf05Sopenharmony_ci */ 473f4cbf05Sopenharmony_ci#define INITIAL_PRIMARY_VALUE (1 << 28) 483f4cbf05Sopenharmony_ci 493f4cbf05Sopenharmony_ciclass RefBase; 503f4cbf05Sopenharmony_ci 513f4cbf05Sopenharmony_ci#if ((defined DEBUG_REFBASE) && (!defined PRINT_TRACK_AT_ONCE)) 523f4cbf05Sopenharmony_ciclass RefTracker; 533f4cbf05Sopenharmony_ci#endif 543f4cbf05Sopenharmony_ci 553f4cbf05Sopenharmony_ci/** 563f4cbf05Sopenharmony_ci * @ingroup SmartPointer 573f4cbf05Sopenharmony_ci * @brief Reference counter class. Such a class records two kinds 583f4cbf05Sopenharmony_ci * of references to the corresponding RefBase object and one kind 593f4cbf05Sopenharmony_ci * of references to the RefCounter object itself. 603f4cbf05Sopenharmony_ci * 613f4cbf05Sopenharmony_ci * There are two different references for a single object.\n 623f4cbf05Sopenharmony_ci * A strong reference holds the reference directly pointing to the object, 633f4cbf05Sopenharmony_ci * and the object should be alive as long as the strong reference exists.\n 643f4cbf05Sopenharmony_ci * A weak reference holds a reference indirectly pointing to the object, 653f4cbf05Sopenharmony_ci * and the object is not always alive/existent 663f4cbf05Sopenharmony_ci * even if the weak reference exists. 673f4cbf05Sopenharmony_ci * @note The preceding descriptions are valid only when smart pointers 683f4cbf05Sopenharmony_ci * are properly used. 693f4cbf05Sopenharmony_ci */ 703f4cbf05Sopenharmony_ciclass RefCounter { 713f4cbf05Sopenharmony_cipublic: 723f4cbf05Sopenharmony_ci /** 733f4cbf05Sopenharmony_ci * @brief Callback function used to destroy the corresponding 743f4cbf05Sopenharmony_ci * RefBase object. 753f4cbf05Sopenharmony_ci */ 763f4cbf05Sopenharmony_ci using RefPtrCallback = std::function<void()>; 773f4cbf05Sopenharmony_ci friend class RefBase; 783f4cbf05Sopenharmony_ci 793f4cbf05Sopenharmony_ci RefCounter(); 803f4cbf05Sopenharmony_ci 813f4cbf05Sopenharmony_ci explicit RefCounter(RefCounter *counter); 823f4cbf05Sopenharmony_ci 833f4cbf05Sopenharmony_ci RefCounter &operator=(const RefCounter &counter); 843f4cbf05Sopenharmony_ci 853f4cbf05Sopenharmony_ci virtual ~RefCounter(); 863f4cbf05Sopenharmony_ci 873f4cbf05Sopenharmony_ci /** 883f4cbf05Sopenharmony_ci * @brief Sets the callback function. 893f4cbf05Sopenharmony_ci * 903f4cbf05Sopenharmony_ci * @param callback Callback function used to delete 913f4cbf05Sopenharmony_ci * the corresponding RefBase object. 923f4cbf05Sopenharmony_ci */ 933f4cbf05Sopenharmony_ci void SetCallback(const RefPtrCallback& callback); 943f4cbf05Sopenharmony_ci 953f4cbf05Sopenharmony_ci /** 963f4cbf05Sopenharmony_ci * @brief Removes the current callback function by setting it to a `nullptr`. 973f4cbf05Sopenharmony_ci */ 983f4cbf05Sopenharmony_ci void RemoveCallback(); 993f4cbf05Sopenharmony_ci 1003f4cbf05Sopenharmony_ci /** 1013f4cbf05Sopenharmony_ci * @brief Gets the count of references to the RefCounter object. 1023f4cbf05Sopenharmony_ci * 1033f4cbf05Sopenharmony_ci * @return Count of references to the RefCounter object. 1043f4cbf05Sopenharmony_ci */ 1053f4cbf05Sopenharmony_ci int GetRefCount(); 1063f4cbf05Sopenharmony_ci 1073f4cbf05Sopenharmony_ci /** 1083f4cbf05Sopenharmony_ci * @brief Increments the count of references to the RefCounter object by 1. 1093f4cbf05Sopenharmony_ci */ 1103f4cbf05Sopenharmony_ci void IncRefCount(); 1113f4cbf05Sopenharmony_ci 1123f4cbf05Sopenharmony_ci /** 1133f4cbf05Sopenharmony_ci * @brief Decrements the count of references to the RefCounter object by 1. 1143f4cbf05Sopenharmony_ci * 1153f4cbf05Sopenharmony_ci * Once the count reaches 0 after being decremented, 1163f4cbf05Sopenharmony_ci * `delete this` will be called to deallocate this RefCounter object. 1173f4cbf05Sopenharmony_ci */ 1183f4cbf05Sopenharmony_ci void DecRefCount(); 1193f4cbf05Sopenharmony_ci 1203f4cbf05Sopenharmony_ci /** 1213f4cbf05Sopenharmony_ci * @brief Checks if the pointer to the callback function is a `nullptr`. 1223f4cbf05Sopenharmony_ci * 1233f4cbf05Sopenharmony_ci * @return `true` if the callback function is a `nullptr`; 1243f4cbf05Sopenharmony_ci * `false` otherwise. 1253f4cbf05Sopenharmony_ci */ 1263f4cbf05Sopenharmony_ci bool IsRefPtrValid(); 1273f4cbf05Sopenharmony_ci 1283f4cbf05Sopenharmony_ci /** 1293f4cbf05Sopenharmony_ci * @brief Increments the count of strong references to the 1303f4cbf05Sopenharmony_ci * corresponding RefBase object by 1. 1313f4cbf05Sopenharmony_ci * 1323f4cbf05Sopenharmony_ci * @return Original count before increment. 1333f4cbf05Sopenharmony_ci */ 1343f4cbf05Sopenharmony_ci int IncStrongRefCount(const void *objectId); 1353f4cbf05Sopenharmony_ci 1363f4cbf05Sopenharmony_ci /** 1373f4cbf05Sopenharmony_ci * @brief Decrements the count of strong references to the 1383f4cbf05Sopenharmony_ci * corresponding RefBase object by 1. 1393f4cbf05Sopenharmony_ci * 1403f4cbf05Sopenharmony_ci * @return Original count before decrement. 1413f4cbf05Sopenharmony_ci * @note If the strong reference never exists, 1423f4cbf05Sopenharmony_ci * decrement will be ineffective. 1433f4cbf05Sopenharmony_ci */ 1443f4cbf05Sopenharmony_ci int DecStrongRefCount(const void *objectId); 1453f4cbf05Sopenharmony_ci 1463f4cbf05Sopenharmony_ci /** 1473f4cbf05Sopenharmony_ci * @brief Gets the count of strong references to the 1483f4cbf05Sopenharmony_ci * corresponding RefBase object. 1493f4cbf05Sopenharmony_ci * 1503f4cbf05Sopenharmony_ci * @return Count of strong references. 1513f4cbf05Sopenharmony_ci */ 1523f4cbf05Sopenharmony_ci int GetStrongRefCount(); 1533f4cbf05Sopenharmony_ci 1543f4cbf05Sopenharmony_ci /** 1553f4cbf05Sopenharmony_ci * @brief Increments the count weak references to the 1563f4cbf05Sopenharmony_ci * corresponding RefBase object by 1. 1573f4cbf05Sopenharmony_ci * 1583f4cbf05Sopenharmony_ci * @return Original count before increment. 1593f4cbf05Sopenharmony_ci */ 1603f4cbf05Sopenharmony_ci int IncWeakRefCount(const void *objectId); 1613f4cbf05Sopenharmony_ci 1623f4cbf05Sopenharmony_ci /** 1633f4cbf05Sopenharmony_ci * @brief Decrements the count of weak references to the 1643f4cbf05Sopenharmony_ci * corresponding RefBase object by 1. 1653f4cbf05Sopenharmony_ci * 1663f4cbf05Sopenharmony_ci * @return Original (before decrement) value of atomicWeak_. 1673f4cbf05Sopenharmony_ci * @note If the count reaches 0 after being decremented, the 1683f4cbf05Sopenharmony_ci * corresponding RefBase object with no strong reference ever, 1693f4cbf05Sopenharmony_ci * or the RefBase object with 0 strong reference but an extended 1703f4cbf05Sopenharmony_ci * 'life time', will be deallocated. 1713f4cbf05Sopenharmony_ci */ 1723f4cbf05Sopenharmony_ci int DecWeakRefCount(const void *objectId); 1733f4cbf05Sopenharmony_ci 1743f4cbf05Sopenharmony_ci /** 1753f4cbf05Sopenharmony_ci * @brief Gets the count of weak references to the 1763f4cbf05Sopenharmony_ci * corresponding RefBase object. 1773f4cbf05Sopenharmony_ci * 1783f4cbf05Sopenharmony_ci * @return Count of weak references. 1793f4cbf05Sopenharmony_ci */ 1803f4cbf05Sopenharmony_ci int GetWeakRefCount(); 1813f4cbf05Sopenharmony_ci 1823f4cbf05Sopenharmony_ci /** 1833f4cbf05Sopenharmony_ci * @brief Sets the number of attempts to increment. 1843f4cbf05Sopenharmony_ci */ 1853f4cbf05Sopenharmony_ci void SetAttemptAcquire(); 1863f4cbf05Sopenharmony_ci 1873f4cbf05Sopenharmony_ci /** 1883f4cbf05Sopenharmony_ci * @brief Get the current times of attempts,this interface is only for IPC use. 1893f4cbf05Sopenharmony_ci */ 1903f4cbf05Sopenharmony_ci int GetAttemptAcquire(); 1913f4cbf05Sopenharmony_ci 1923f4cbf05Sopenharmony_ci /** 1933f4cbf05Sopenharmony_ci * @brief Check if the number of attempts is greater than 0. 1943f4cbf05Sopenharmony_ci * 1953f4cbf05Sopenharmony_ci * @return `true` if the number of attempts is greater than 0; 1963f4cbf05Sopenharmony_ci * `false` otherwise. 1973f4cbf05Sopenharmony_ci */ 1983f4cbf05Sopenharmony_ci bool IsAttemptAcquireSet(); 1993f4cbf05Sopenharmony_ci 2003f4cbf05Sopenharmony_ci /** 2013f4cbf05Sopenharmony_ci * @brief Clears number of attempts to increment. 2023f4cbf05Sopenharmony_ci */ 2033f4cbf05Sopenharmony_ci void ClearAttemptAcquire(); 2043f4cbf05Sopenharmony_ci 2053f4cbf05Sopenharmony_ci /** 2063f4cbf05Sopenharmony_ci * @brief Attempts to increment the count of strong references to the 2073f4cbf05Sopenharmony_ci * corresponding RefBase object by 1. 2083f4cbf05Sopenharmony_ci * 2093f4cbf05Sopenharmony_ci * @param outCount If the attempt success, the original value 2103f4cbf05Sopenharmony_ci * (before increment) of the count will be stored here. 2113f4cbf05Sopenharmony_ci * @return `true` if the attempt is successful; `false` otherwise. 2123f4cbf05Sopenharmony_ci */ 2133f4cbf05Sopenharmony_ci bool AttemptIncStrongRef(const void *objectId, int &outCount); 2143f4cbf05Sopenharmony_ci 2153f4cbf05Sopenharmony_ci // Only for IPC use. 2163f4cbf05Sopenharmony_ci /** 2173f4cbf05Sopenharmony_ci * @brief Attempts to increment the count of strong references to the 2183f4cbf05Sopenharmony_ci * the corresponding RefBase object by 1 (simplified). 2193f4cbf05Sopenharmony_ci * 2203f4cbf05Sopenharmony_ci * @return `true` if the attempt is successful; `false` otherwise. 2213f4cbf05Sopenharmony_ci * @note Only for IPC use. 2223f4cbf05Sopenharmony_ci */ 2233f4cbf05Sopenharmony_ci bool AttemptIncStrong(const void *objectId); 2243f4cbf05Sopenharmony_ci 2253f4cbf05Sopenharmony_ci /** 2263f4cbf05Sopenharmony_ci * @brief Checks if the corresponding RefBase object 2273f4cbf05Sopenharmony_ci * has an extended life-time. 2283f4cbf05Sopenharmony_ci * 2293f4cbf05Sopenharmony_ci * @return `true` if success; `false` otherwise. 2303f4cbf05Sopenharmony_ci */ 2313f4cbf05Sopenharmony_ci bool IsLifeTimeExtended(); 2323f4cbf05Sopenharmony_ci 2333f4cbf05Sopenharmony_ci /** 2343f4cbf05Sopenharmony_ci * @brief Extends the life-time of corresponding RefBase object. 2353f4cbf05Sopenharmony_ci * 2363f4cbf05Sopenharmony_ci * This allows the corresponding object keep alive 2373f4cbf05Sopenharmony_ci * even if there is no strong reference. 2383f4cbf05Sopenharmony_ci * @note The RefBase object will be deallocated 2393f4cbf05Sopenharmony_ci * if the count of weak references also reaches 0. 2403f4cbf05Sopenharmony_ci */ 2413f4cbf05Sopenharmony_ci void ExtendObjectLifetime(); 2423f4cbf05Sopenharmony_ci 2433f4cbf05Sopenharmony_ci#ifndef EMULATOR_PLATFORM 2443f4cbf05Sopenharmony_ci using CanPromote = std::function<bool()>; 2453f4cbf05Sopenharmony_ci 2463f4cbf05Sopenharmony_ci void SetCanPromote(const CanPromote& canPromote); 2473f4cbf05Sopenharmony_ci 2483f4cbf05Sopenharmony_ci void RemoveCanPromote(); 2493f4cbf05Sopenharmony_ci 2503f4cbf05Sopenharmony_ci bool IsCanPromoteValid(); 2513f4cbf05Sopenharmony_ci#endif 2523f4cbf05Sopenharmony_ci 2533f4cbf05Sopenharmony_ci#if ((defined DEBUG_REFBASE) && (!defined TRACK_ALL)) 2543f4cbf05Sopenharmony_ci /** 2553f4cbf05Sopenharmony_ci * @brief Enables tracking. It is applicable to debugging only. 2563f4cbf05Sopenharmony_ci */ 2573f4cbf05Sopenharmony_ci void EnableTracker(); 2583f4cbf05Sopenharmony_ci#endif 2593f4cbf05Sopenharmony_ci 2603f4cbf05Sopenharmony_ciprivate: 2613f4cbf05Sopenharmony_ci void DebugRefBase(const void *objectId); 2623f4cbf05Sopenharmony_ci 2633f4cbf05Sopenharmony_ci std::atomic<int> atomicStrong_; // = (num of sptr) or Initial-value 2643f4cbf05Sopenharmony_ci std::atomic<int> atomicWeak_; // = (num of sptr)+(num of WeakRefCounter) 2653f4cbf05Sopenharmony_ci std::atomic<int> atomicRefCount_; // = (num of WeakRefCounter) + 1 2663f4cbf05Sopenharmony_ci std::atomic<unsigned int> atomicFlags_; // Life-time extended flag 2673f4cbf05Sopenharmony_ci std::atomic<int> atomicAttempt_; // Number of attempts 2683f4cbf05Sopenharmony_ci RefPtrCallback callback_ = nullptr; // Callback function to deallocate the corresponding RefBase object 2693f4cbf05Sopenharmony_ci static constexpr unsigned int FLAG_EXTEND_LIFE_TIME = 0x00000002; // Extended life-time bit to be set via logic-OR 2703f4cbf05Sopenharmony_ci#ifndef EMULATOR_PLATFORM 2713f4cbf05Sopenharmony_ci CanPromote canPromote_ = nullptr; 2723f4cbf05Sopenharmony_ci#endif 2733f4cbf05Sopenharmony_ci#ifdef DEBUG_REFBASE 2743f4cbf05Sopenharmony_ci#ifdef TRACK_ALL 2753f4cbf05Sopenharmony_ci bool enableTrack = true; 2763f4cbf05Sopenharmony_ci#else 2773f4cbf05Sopenharmony_ci bool enableTrack = false; 2783f4cbf05Sopenharmony_ci#endif 2793f4cbf05Sopenharmony_ci std::mutex trackerMutex; // To ensure refTracker be thread-safe 2803f4cbf05Sopenharmony_ci#ifdef PRINT_TRACK_AT_ONCE 2813f4cbf05Sopenharmony_ci void PrintRefs(const void* objectId); 2823f4cbf05Sopenharmony_ci#else 2833f4cbf05Sopenharmony_ci RefTracker* refTracker = nullptr; 2843f4cbf05Sopenharmony_ci void GetNewTrace(const void* objectId); 2853f4cbf05Sopenharmony_ci void PrintTracker(); 2863f4cbf05Sopenharmony_ci#endif 2873f4cbf05Sopenharmony_ci#endif 2883f4cbf05Sopenharmony_ci}; 2893f4cbf05Sopenharmony_ci 2903f4cbf05Sopenharmony_ci/** 2913f4cbf05Sopenharmony_ci * @ingroup SmartPointer 2923f4cbf05Sopenharmony_ci * @brief An intermediate class to represent the weak reference 2933f4cbf05Sopenharmony_ci * to the correspond RefBase object. 2943f4cbf05Sopenharmony_ci * 2953f4cbf05Sopenharmony_ci * A WeakRefCounter object can be shared by multiple wptr objects.\n 2963f4cbf05Sopenharmony_ci * It holds the references to the corresponding RefBase and RefCounter object. 2973f4cbf05Sopenharmony_ci * Those two references will be set as `nullptr` when the weak referenced 2983f4cbf05Sopenharmony_ci * target and its RefCounter object are deallocated. The WeakRefCounter 2993f4cbf05Sopenharmony_ci * object can remain alive even if the referenced target is deallocated. 3003f4cbf05Sopenharmony_ci */ 3013f4cbf05Sopenharmony_ciclass WeakRefCounter { 3023f4cbf05Sopenharmony_cipublic: 3033f4cbf05Sopenharmony_ci /** 3043f4cbf05Sopenharmony_ci * @brief Constructs a WeakRefCounter object. 3053f4cbf05Sopenharmony_ci * 3063f4cbf05Sopenharmony_ci * @param counter Pointer to corresponding RefCounter object. 3073f4cbf05Sopenharmony_ci * @param cookie Pointer to corresponding RefBase object. 3083f4cbf05Sopenharmony_ci */ 3093f4cbf05Sopenharmony_ci WeakRefCounter(RefCounter *counter, void *cookie); 3103f4cbf05Sopenharmony_ci 3113f4cbf05Sopenharmony_ci virtual ~WeakRefCounter(); 3123f4cbf05Sopenharmony_ci 3133f4cbf05Sopenharmony_ci /** 3143f4cbf05Sopenharmony_ci * @brief Gets the current pointer to the corresponding RefBase object. 3153f4cbf05Sopenharmony_ci * 3163f4cbf05Sopenharmony_ci * @return A void pointer to the RefBase object. 3173f4cbf05Sopenharmony_ci * If the corresponding object is not alive, a `nullptr` will be returned. 3183f4cbf05Sopenharmony_ci * @note A void pointer means that you should cast it to the real type, 3193f4cbf05Sopenharmony_ci * since it can be any subclass of RefBase. 3203f4cbf05Sopenharmony_ci */ 3213f4cbf05Sopenharmony_ci void *GetRefPtr(); 3223f4cbf05Sopenharmony_ci 3233f4cbf05Sopenharmony_ci /** 3243f4cbf05Sopenharmony_ci * @brief Increments the count of references to this WeakRefCounter object. 3253f4cbf05Sopenharmony_ci * 3263f4cbf05Sopenharmony_ci * @note This count is different from the count of weak references 3273f4cbf05Sopenharmony_ci * in RefCounter. It is equal to the count of wptrs directly 3283f4cbf05Sopenharmony_ci * referenced to this WeakRefCount object. 3293f4cbf05Sopenharmony_ci * @see RefCounter 3303f4cbf05Sopenharmony_ci */ 3313f4cbf05Sopenharmony_ci void IncWeakRefCount(const void *objectId); 3323f4cbf05Sopenharmony_ci 3333f4cbf05Sopenharmony_ci /** 3343f4cbf05Sopenharmony_ci * @brief Decrements the count of references to this WeakRefCounter object. 3353f4cbf05Sopenharmony_ci * 3363f4cbf05Sopenharmony_ci * @note This WeakRefCounter object will be deallocated when this count 3373f4cbf05Sopenharmony_ci * reaches 0. 3383f4cbf05Sopenharmony_ci */ 3393f4cbf05Sopenharmony_ci void DecWeakRefCount(const void *objectId); 3403f4cbf05Sopenharmony_ci 3413f4cbf05Sopenharmony_ci /** 3423f4cbf05Sopenharmony_ci * @brief Gets the count recorded by this WeakRefCounter object. 3433f4cbf05Sopenharmony_ci * 3443f4cbf05Sopenharmony_ci * @return Count recorded by this WeakRefCounter object. 3453f4cbf05Sopenharmony_ci * @note The count is different from that in RefCounter. 3463f4cbf05Sopenharmony_ci * @see RefCounter::GetWeakRefCount() 3473f4cbf05Sopenharmony_ci */ 3483f4cbf05Sopenharmony_ci int GetWeakRefCount() const; 3493f4cbf05Sopenharmony_ci 3503f4cbf05Sopenharmony_ci /** 3513f4cbf05Sopenharmony_ci * @brief Attempts to increment the count of strong references to 3523f4cbf05Sopenharmony_ci * the corresponding RefBase object (to promote a wptr to a sptr). 3533f4cbf05Sopenharmony_ci * 3543f4cbf05Sopenharmony_ci * @return `true` after a success increment. 3553f4cbf05Sopenharmony_ci */ 3563f4cbf05Sopenharmony_ci bool AttemptIncStrongRef(const void *objectId); 3573f4cbf05Sopenharmony_ci 3583f4cbf05Sopenharmony_ciprivate: 3593f4cbf05Sopenharmony_ci std::atomic<int> atomicWeak_; // Count of references to this 3603f4cbf05Sopenharmony_ci // WeakRefCounter object 3613f4cbf05Sopenharmony_ci // The value is equal to the count of wptrs 3623f4cbf05Sopenharmony_ci // that references this WeakRefCounter object. 3633f4cbf05Sopenharmony_ci RefCounter *refCounter_ = nullptr; // Reference to the RefCounter object of 3643f4cbf05Sopenharmony_ci // the corresponding RefBase object 3653f4cbf05Sopenharmony_ci void *cookie_ = nullptr; // Pointer to the corresponding RefBase object 3663f4cbf05Sopenharmony_ci}; 3673f4cbf05Sopenharmony_ci 3683f4cbf05Sopenharmony_ci/** 3693f4cbf05Sopenharmony_ci * @ingroup SmartPointer 3703f4cbf05Sopenharmony_ci * @brief A base class of subclasses that can be managed by SmartPointer. 3713f4cbf05Sopenharmony_ci * 3723f4cbf05Sopenharmony_ci * @note All classes which intend to be managed by SmartPointer should be 3733f4cbf05Sopenharmony_ci * derived from RefBase. 3743f4cbf05Sopenharmony_ci */ 3753f4cbf05Sopenharmony_ciclass RefBase { 3763f4cbf05Sopenharmony_cipublic: 3773f4cbf05Sopenharmony_ci RefBase(); 3783f4cbf05Sopenharmony_ci 3793f4cbf05Sopenharmony_ci /** 3803f4cbf05Sopenharmony_ci * @brief Copy constructor of RefBase. 3813f4cbf05Sopenharmony_ci * 3823f4cbf05Sopenharmony_ci * @note This function constructs a new RefCounter object 3833f4cbf05Sopenharmony_ci * and binds it to the RefBase object. 3843f4cbf05Sopenharmony_ci */ 3853f4cbf05Sopenharmony_ci RefBase(const RefBase &); 3863f4cbf05Sopenharmony_ci 3873f4cbf05Sopenharmony_ci /** 3883f4cbf05Sopenharmony_ci * @brief Copy assignment operator of RefBase. 3893f4cbf05Sopenharmony_ci * 3903f4cbf05Sopenharmony_ci * @note This function unbinds this RefBase object from the 3913f4cbf05Sopenharmony_ci * original RefCounter object, and then binds it to the 3923f4cbf05Sopenharmony_ci * newly constructed RefCounter object. 3933f4cbf05Sopenharmony_ci */ 3943f4cbf05Sopenharmony_ci RefBase &operator=(const RefBase &); 3953f4cbf05Sopenharmony_ci 3963f4cbf05Sopenharmony_ci /** 3973f4cbf05Sopenharmony_ci * @brief Move constructor of RefBase. 3983f4cbf05Sopenharmony_ci */ 3993f4cbf05Sopenharmony_ci RefBase(RefBase &&other) noexcept; 4003f4cbf05Sopenharmony_ci 4013f4cbf05Sopenharmony_ci /** 4023f4cbf05Sopenharmony_ci * @brief Move assignment operator of RefBase. 4033f4cbf05Sopenharmony_ci * 4043f4cbf05Sopenharmony_ci * @note This function binds this RefBase object with the RefCounter 4053f4cbf05Sopenharmony_ci * object of the argument `other`, which will unbind the 4063f4cbf05Sopenharmony_ci * RefCounter object. No counts operation will be processed. 4073f4cbf05Sopenharmony_ci */ 4083f4cbf05Sopenharmony_ci RefBase &operator=(RefBase &&other) noexcept; 4093f4cbf05Sopenharmony_ci 4103f4cbf05Sopenharmony_ci virtual ~RefBase(); 4113f4cbf05Sopenharmony_ci 4123f4cbf05Sopenharmony_ci /** 4133f4cbf05Sopenharmony_ci * @brief Callback function to deallocate this object. 4143f4cbf05Sopenharmony_ci * 4153f4cbf05Sopenharmony_ci * This function provides the default implementation to deallocate 4163f4cbf05Sopenharmony_ci * this RefBase object by simply calling `delete(this)`. 4173f4cbf05Sopenharmony_ci */ 4183f4cbf05Sopenharmony_ci virtual void RefPtrCallback(); 4193f4cbf05Sopenharmony_ci 4203f4cbf05Sopenharmony_ci /** 4213f4cbf05Sopenharmony_ci * @brief Extends the life time of the RefBase object. 4223f4cbf05Sopenharmony_ci * 4233f4cbf05Sopenharmony_ci * @note The object whose life time has been extended will not be 4243f4cbf05Sopenharmony_ci * deallocated if the count of weak references, instead of strong 4253f4cbf05Sopenharmony_ci * references, reaches 0. 4263f4cbf05Sopenharmony_ci */ 4273f4cbf05Sopenharmony_ci void ExtendObjectLifetime(); 4283f4cbf05Sopenharmony_ci 4293f4cbf05Sopenharmony_ci /** 4303f4cbf05Sopenharmony_ci * @brief Increments the count of strong references. 4313f4cbf05Sopenharmony_ci * 4323f4cbf05Sopenharmony_ci * `OnFirstStrongRef()`, which is an empty function by default, 4333f4cbf05Sopenharmony_ci * will be called when the first strong reference is established. 4343f4cbf05Sopenharmony_ci * 4353f4cbf05Sopenharmony_ci * @note This function automatically increments the count of weak 4363f4cbf05Sopenharmony_ci * references meanwhile. 4373f4cbf05Sopenharmony_ci */ 4383f4cbf05Sopenharmony_ci void IncStrongRef(const void *objectId); 4393f4cbf05Sopenharmony_ci 4403f4cbf05Sopenharmony_ci /** 4413f4cbf05Sopenharmony_ci * @brief Decrements the count of strong references. 4423f4cbf05Sopenharmony_ci * 4433f4cbf05Sopenharmony_ci * If the life time is not extended, this object will be deallocated 4443f4cbf05Sopenharmony_ci * when the count of strong references reaches 0.\n 4453f4cbf05Sopenharmony_ci * `OnLastStrongRef()`, which is an empty function by default, 4463f4cbf05Sopenharmony_ci * will be called when the last strong reference is deleted. 4473f4cbf05Sopenharmony_ci */ 4483f4cbf05Sopenharmony_ci void DecStrongRef(const void *objectId); 4493f4cbf05Sopenharmony_ci 4503f4cbf05Sopenharmony_ci /** 4513f4cbf05Sopenharmony_ci * @brief Gets the count of strong references. 4523f4cbf05Sopenharmony_ci * 4533f4cbf05Sopenharmony_ci * @return Count of strong references. The value is 0 if the 4543f4cbf05Sopenharmony_ci * corresponding RefCounter object does not exist. 4553f4cbf05Sopenharmony_ci * @note This function is valid only when corresponding RefCounter 4563f4cbf05Sopenharmony_ci * object exists. 4573f4cbf05Sopenharmony_ci */ 4583f4cbf05Sopenharmony_ci int GetSptrRefCount(); 4593f4cbf05Sopenharmony_ci 4603f4cbf05Sopenharmony_ci /** 4613f4cbf05Sopenharmony_ci * @brief Creates a weak reference to this RefBase object. 4623f4cbf05Sopenharmony_ci * 4633f4cbf05Sopenharmony_ci * @param cookie Void pointer to this RefBase object. 4643f4cbf05Sopenharmony_ci * @return Pointer to the newly created WeakRefCounter object. 4653f4cbf05Sopenharmony_ci * @note Use this function with related functions of wptr. 4663f4cbf05Sopenharmony_ci * Do not use it independently. 4673f4cbf05Sopenharmony_ci */ 4683f4cbf05Sopenharmony_ci WeakRefCounter *CreateWeakRef(void *cookie); 4693f4cbf05Sopenharmony_ci 4703f4cbf05Sopenharmony_ci /** 4713f4cbf05Sopenharmony_ci * @brief Gets the pointer to corresponding counter object. 4723f4cbf05Sopenharmony_ci * 4733f4cbf05Sopenharmony_ci * @return Pointer to the counter object. 4743f4cbf05Sopenharmony_ci */ 4753f4cbf05Sopenharmony_ci RefCounter *GetRefCounter() const; 4763f4cbf05Sopenharmony_ci 4773f4cbf05Sopenharmony_ci /** 4783f4cbf05Sopenharmony_ci * @brief Increments the count of weak references. 4793f4cbf05Sopenharmony_ci * 4803f4cbf05Sopenharmony_ci * @note This function is valid only when corresponding RefCounter 4813f4cbf05Sopenharmony_ci * object exists. 4823f4cbf05Sopenharmony_ci */ 4833f4cbf05Sopenharmony_ci void IncWeakRef(const void *objectId); 4843f4cbf05Sopenharmony_ci 4853f4cbf05Sopenharmony_ci /** 4863f4cbf05Sopenharmony_ci * @brief Decrements the count of weak references. 4873f4cbf05Sopenharmony_ci * 4883f4cbf05Sopenharmony_ci * @note This function is valid only when corresponding RefCounter 4893f4cbf05Sopenharmony_ci * object exists. 4903f4cbf05Sopenharmony_ci */ 4913f4cbf05Sopenharmony_ci void DecWeakRef(const void *objectId); 4923f4cbf05Sopenharmony_ci 4933f4cbf05Sopenharmony_ci /** 4943f4cbf05Sopenharmony_ci * @brief Gets the count of weak references. 4953f4cbf05Sopenharmony_ci * 4963f4cbf05Sopenharmony_ci * @return Count of weak references. The value is 0 if the corresponding 4973f4cbf05Sopenharmony_ci * RefCounter object does not exist. 4983f4cbf05Sopenharmony_ci */ 4993f4cbf05Sopenharmony_ci int GetWptrRefCount(); 5003f4cbf05Sopenharmony_ci 5013f4cbf05Sopenharmony_ci /** 5023f4cbf05Sopenharmony_ci * @brief Attempts to increment the count of strong references. 5033f4cbf05Sopenharmony_ci * 5043f4cbf05Sopenharmony_ci * `OnFirstStrongRef()`, which is an empty function by default, will be 5053f4cbf05Sopenharmony_ci * called when the first strong reference is established. 5063f4cbf05Sopenharmony_ci * 5073f4cbf05Sopenharmony_ci * @return `true` if the increment is successful; `false` otherwise. 5083f4cbf05Sopenharmony_ci * @note The count of attempts will increment by 1 5093f4cbf05Sopenharmony_ci * after a successful increment. 5103f4cbf05Sopenharmony_ci */ 5113f4cbf05Sopenharmony_ci bool AttemptAcquire(const void *objectId); 5123f4cbf05Sopenharmony_ci 5133f4cbf05Sopenharmony_ci /** 5143f4cbf05Sopenharmony_ci * @brief Check attempt acquire is setted,this interface is only for IPC use. 5153f4cbf05Sopenharmony_ci * This interface must come after the RefBase::AttemptIncStrong or RefBase::AttemptAcquire function, 5163f4cbf05Sopenharmony_ci * And ensuring thread safety in multi-threaded scenarios. 5173f4cbf05Sopenharmony_ci * 5183f4cbf05Sopenharmony_ci * @note This fuction is extracted from `IncStrongRef()` 5193f4cbf05Sopenharmony_ci * It is only for IPC use. 5203f4cbf05Sopenharmony_ci */ 5213f4cbf05Sopenharmony_ci void CheckIsAttemptAcquireSet(const void *objectId); 5223f4cbf05Sopenharmony_ci 5233f4cbf05Sopenharmony_ci /** 5243f4cbf05Sopenharmony_ci * @brief Attempts to increment the count of strong references. 5253f4cbf05Sopenharmony_ci * 5263f4cbf05Sopenharmony_ci * `OnFirstStrongRef()`, which is an empty function by default, will be 5273f4cbf05Sopenharmony_ci * called when the first strong reference is established. 5283f4cbf05Sopenharmony_ci * @return `true` if the increment is successful; `false` otherwise. 5293f4cbf05Sopenharmony_ci * @note Use this function in the copy constructor of sptr in scenario of 5303f4cbf05Sopenharmony_ci * interaction between sptr and wptr. Avoid using it independently. 5313f4cbf05Sopenharmony_ci */ 5323f4cbf05Sopenharmony_ci bool AttemptIncStrongRef(const void *objectId); 5333f4cbf05Sopenharmony_ci 5343f4cbf05Sopenharmony_ci // Only for IPC use. 5353f4cbf05Sopenharmony_ci /** 5363f4cbf05Sopenharmony_ci * @brief Attempts to increment the count of strong references. 5373f4cbf05Sopenharmony_ci * 5383f4cbf05Sopenharmony_ci * @return `true` if the increment is successful; `false` otherwise. 5393f4cbf05Sopenharmony_ci * @note If the operation is successful, the count of successful attempts 5403f4cbf05Sopenharmony_ci * will increment by 1. 5413f4cbf05Sopenharmony_ci * @note This function is a simplified version of `AttemptAcquire`. 5423f4cbf05Sopenharmony_ci * It is only for IPC use. 5433f4cbf05Sopenharmony_ci */ 5443f4cbf05Sopenharmony_ci bool AttemptIncStrong(const void *objectId); 5453f4cbf05Sopenharmony_ci 5463f4cbf05Sopenharmony_ci /** 5473f4cbf05Sopenharmony_ci * @brief Checks if the count of successful attempts is greater than 0. 5483f4cbf05Sopenharmony_ci * 5493f4cbf05Sopenharmony_ci * @return `true` if the count of successful attempts is greater than 0; 5503f4cbf05Sopenharmony_ci * `false` if the count of successful attempts is not greater than 0 5513f4cbf05Sopenharmony_ci * or the corresponding RefCounter object does not exist. 5523f4cbf05Sopenharmony_ci */ 5533f4cbf05Sopenharmony_ci bool IsAttemptAcquireSet(); 5543f4cbf05Sopenharmony_ci 5553f4cbf05Sopenharmony_ci /** 5563f4cbf05Sopenharmony_ci * @brief Checks if the life time of this RefBase object has been extended. 5573f4cbf05Sopenharmony_ci * 5583f4cbf05Sopenharmony_ci * @return `true` if the life time of this RefBase object has been extended; 5593f4cbf05Sopenharmony_ci * `false` if the RefBase object has a normal life time or the corresponding 5603f4cbf05Sopenharmony_ci * RefCounter object does not exist. 5613f4cbf05Sopenharmony_ci */ 5623f4cbf05Sopenharmony_ci bool IsExtendLifeTimeSet(); 5633f4cbf05Sopenharmony_ci 5643f4cbf05Sopenharmony_ci /** 5653f4cbf05Sopenharmony_ci * @brief Called when the first strong reference is established. 5663f4cbf05Sopenharmony_ci * 5673f4cbf05Sopenharmony_ci * @note It is an empty function by default. 5683f4cbf05Sopenharmony_ci */ 5693f4cbf05Sopenharmony_ci virtual void OnFirstStrongRef(const void *); 5703f4cbf05Sopenharmony_ci 5713f4cbf05Sopenharmony_ci /** 5723f4cbf05Sopenharmony_ci * @brief Called when the last strong reference is deleted. 5733f4cbf05Sopenharmony_ci * 5743f4cbf05Sopenharmony_ci * @note It is an empty function by default. 5753f4cbf05Sopenharmony_ci */ 5763f4cbf05Sopenharmony_ci virtual void OnLastStrongRef(const void *); 5773f4cbf05Sopenharmony_ci 5783f4cbf05Sopenharmony_ci /** 5793f4cbf05Sopenharmony_ci * @brief Called when the last weak reference is deleted. 5803f4cbf05Sopenharmony_ci * 5813f4cbf05Sopenharmony_ci * @note It is an empty function by default. 5823f4cbf05Sopenharmony_ci */ 5833f4cbf05Sopenharmony_ci virtual void OnLastWeakRef(const void *); 5843f4cbf05Sopenharmony_ci 5853f4cbf05Sopenharmony_ci /** 5863f4cbf05Sopenharmony_ci * @brief Called when `wptr::Promote()` is invoked. 5873f4cbf05Sopenharmony_ci * 5883f4cbf05Sopenharmony_ci * @return `true` if success; `false` otherwise. 5893f4cbf05Sopenharmony_ci */ 5903f4cbf05Sopenharmony_ci virtual bool OnAttemptPromoted(const void *); 5913f4cbf05Sopenharmony_ci 5923f4cbf05Sopenharmony_ci /** 5933f4cbf05Sopenharmony_ci * @brief Enables tracking of the RefBase object. This function will 5943f4cbf05Sopenharmony_ci * be implemented only if DEBUG_REFBASE, but not TRACK_ALL, is defined. 5953f4cbf05Sopenharmony_ci */ 5963f4cbf05Sopenharmony_ci void EnableTracker(); 5973f4cbf05Sopenharmony_ci 5983f4cbf05Sopenharmony_ci#ifndef EMULATOR_PLATFORM 5993f4cbf05Sopenharmony_ci virtual bool CanPromote(); 6003f4cbf05Sopenharmony_ci#endif 6013f4cbf05Sopenharmony_ci 6023f4cbf05Sopenharmony_ciprivate: 6033f4cbf05Sopenharmony_ci RefCounter *refs_ = nullptr; // Pointer to the corresponding reference 6043f4cbf05Sopenharmony_ci // counter of this RefBase object 6053f4cbf05Sopenharmony_ci}; 6063f4cbf05Sopenharmony_ci 6073f4cbf05Sopenharmony_citemplate <typename T> 6083f4cbf05Sopenharmony_ciclass wptr; 6093f4cbf05Sopenharmony_ci 6103f4cbf05Sopenharmony_ci/** 6113f4cbf05Sopenharmony_ci * @ingroup SmartPointer 6123f4cbf05Sopenharmony_ci * @brief Strong reference smart pointer to a RefBase object 6133f4cbf05Sopenharmony_ci * (or an object of its subclass). 6143f4cbf05Sopenharmony_ci * 6153f4cbf05Sopenharmony_ci * It directly reference the RefBase object. 6163f4cbf05Sopenharmony_ci * 6173f4cbf05Sopenharmony_ci * @tparam T Specific class type managed by sptr. 6183f4cbf05Sopenharmony_ci * This class must inherit from RefBase. 6193f4cbf05Sopenharmony_ci */ 6203f4cbf05Sopenharmony_citemplate <typename T> 6213f4cbf05Sopenharmony_ciclass sptr { 6223f4cbf05Sopenharmony_ci friend class wptr<T>; 6233f4cbf05Sopenharmony_ci 6243f4cbf05Sopenharmony_cipublic: 6253f4cbf05Sopenharmony_ci sptr(); 6263f4cbf05Sopenharmony_ci 6273f4cbf05Sopenharmony_ci ~sptr(); 6283f4cbf05Sopenharmony_ci 6293f4cbf05Sopenharmony_ci /** 6303f4cbf05Sopenharmony_ci * @brief Create a new object with class type (T) and provide a new sptr to manage it. 6313f4cbf05Sopenharmony_ci * 6323f4cbf05Sopenharmony_ci * @note We strongly recommend using `sptr::MakeSptr` to create a object and manage it. 6333f4cbf05Sopenharmony_ci * This approach avoids object pointer leaks, which can avoid many potential memory problems. 6343f4cbf05Sopenharmony_ci * 6353f4cbf05Sopenharmony_ci * @return A sptr which manage a new object with class type (T). 6363f4cbf05Sopenharmony_ci * @param args Constructor parameters of the new object to be managed by sptr. 6373f4cbf05Sopenharmony_ci */ 6383f4cbf05Sopenharmony_ci template <typename... Args> 6393f4cbf05Sopenharmony_ci static inline sptr<T> MakeSptr(Args&&... args); 6403f4cbf05Sopenharmony_ci 6413f4cbf05Sopenharmony_ci /** 6423f4cbf05Sopenharmony_ci * @brief Constructor with the specified object to be managed. 6433f4cbf05Sopenharmony_ci * And We do not recommend using this interface to create an sptr object. 6443f4cbf05Sopenharmony_ci * Using the interface `sptr::MakeSptr` is better 6453f4cbf05Sopenharmony_ci * 6463f4cbf05Sopenharmony_ci * @note A null sptr will be created if `other` is `nullptr`. 6473f4cbf05Sopenharmony_ci * @param other Object to be managed by sptr. 6483f4cbf05Sopenharmony_ci */ 6493f4cbf05Sopenharmony_ci sptr(T *other); 6503f4cbf05Sopenharmony_ci 6513f4cbf05Sopenharmony_ci /** 6523f4cbf05Sopenharmony_ci * @brief Copy constructor for sptr with the managed class type (T). 6533f4cbf05Sopenharmony_ci * 6543f4cbf05Sopenharmony_ci * @param other Input sptr object. 6553f4cbf05Sopenharmony_ci */ 6563f4cbf05Sopenharmony_ci sptr(const sptr<T> &other); 6573f4cbf05Sopenharmony_ci 6583f4cbf05Sopenharmony_ci /** 6593f4cbf05Sopenharmony_ci * @brief Move constructor. 6603f4cbf05Sopenharmony_ci * 6613f4cbf05Sopenharmony_ci * @note `other` will be set to a null sptr. 6623f4cbf05Sopenharmony_ci * @param other Input sptr object. 6633f4cbf05Sopenharmony_ci */ 6643f4cbf05Sopenharmony_ci sptr(sptr<T> &&other); 6653f4cbf05Sopenharmony_ci 6663f4cbf05Sopenharmony_ci /** 6673f4cbf05Sopenharmony_ci * @brief Move assignment operator. 6683f4cbf05Sopenharmony_ci * 6693f4cbf05Sopenharmony_ci * @param other Input sptr object. 6703f4cbf05Sopenharmony_ci * @note The original strong reference in target sptr object will 6713f4cbf05Sopenharmony_ci * be removed. 6723f4cbf05Sopenharmony_ci */ 6733f4cbf05Sopenharmony_ci sptr<T> &operator=(sptr<T> &&other); 6743f4cbf05Sopenharmony_ci 6753f4cbf05Sopenharmony_ci /** 6763f4cbf05Sopenharmony_ci * @brief Copy Constructor for sptr with the managed class type (O). 6773f4cbf05Sopenharmony_ci * 6783f4cbf05Sopenharmony_ci * @tparam O Another specific class type managed by `other`. 6793f4cbf05Sopenharmony_ci * @param other Input sptr object. 6803f4cbf05Sopenharmony_ci */ 6813f4cbf05Sopenharmony_ci template <typename O> 6823f4cbf05Sopenharmony_ci sptr(const sptr<O> &other); 6833f4cbf05Sopenharmony_ci 6843f4cbf05Sopenharmony_ci /** 6853f4cbf05Sopenharmony_ci * @brief Constructor used to promote the process of wptr. 6863f4cbf05Sopenharmony_ci * 6873f4cbf05Sopenharmony_ci * @param p WeakRefCounter object which hold the reference to the 6883f4cbf05Sopenharmony_ci * managed object. 6893f4cbf05Sopenharmony_ci * @param force Used to distinguish from other constructors. 6903f4cbf05Sopenharmony_ci */ 6913f4cbf05Sopenharmony_ci inline sptr(WeakRefCounter *p, bool force); 6923f4cbf05Sopenharmony_ci 6933f4cbf05Sopenharmony_ci /** 6943f4cbf05Sopenharmony_ci * @brief Gets the pointer to the managed object. 6953f4cbf05Sopenharmony_ci * 6963f4cbf05Sopenharmony_ci * @return Pointer of the specific managed class type. 6973f4cbf05Sopenharmony_ci */ 6983f4cbf05Sopenharmony_ci inline T *GetRefPtr() const 6993f4cbf05Sopenharmony_ci { 7003f4cbf05Sopenharmony_ci return refs_; 7013f4cbf05Sopenharmony_ci } 7023f4cbf05Sopenharmony_ci 7033f4cbf05Sopenharmony_ci /** 7043f4cbf05Sopenharmony_ci * @brief Sets the pointer to the managed object. 7053f4cbf05Sopenharmony_ci * 7063f4cbf05Sopenharmony_ci * @param other Another pointer object to be managed by sptr. 7073f4cbf05Sopenharmony_ci * @note Avoid using this function independently. Otherwise, 7083f4cbf05Sopenharmony_ci * a mismatch of the reference count will arise, leading to memory problems. 7093f4cbf05Sopenharmony_ci */ 7103f4cbf05Sopenharmony_ci inline void ForceSetRefPtr(T *other); 7113f4cbf05Sopenharmony_ci 7123f4cbf05Sopenharmony_ci /** 7133f4cbf05Sopenharmony_ci * @brief Removes the reference to the managed object held by current sptr. 7143f4cbf05Sopenharmony_ci * 7153f4cbf05Sopenharmony_ci * @note This function will make this sptr a "null sptr". 7163f4cbf05Sopenharmony_ci */ 7173f4cbf05Sopenharmony_ci void clear(); 7183f4cbf05Sopenharmony_ci 7193f4cbf05Sopenharmony_ci /** 7203f4cbf05Sopenharmony_ci * @brief Type conversion operator. 7213f4cbf05Sopenharmony_ci * 7223f4cbf05Sopenharmony_ci * @return Raw pointer to the managed object. 7233f4cbf05Sopenharmony_ci * @note The sptr object will not be converted. Only the member raw 7243f4cbf05Sopenharmony_ci * pointer will be returned. 7253f4cbf05Sopenharmony_ci */ 7263f4cbf05Sopenharmony_ci inline operator T *() const 7273f4cbf05Sopenharmony_ci { 7283f4cbf05Sopenharmony_ci return refs_; 7293f4cbf05Sopenharmony_ci } 7303f4cbf05Sopenharmony_ci 7313f4cbf05Sopenharmony_ci /** 7323f4cbf05Sopenharmony_ci * @brief Explicit boolean conversion operator. 7333f4cbf05Sopenharmony_ci * 7343f4cbf05Sopenharmony_ci * @return `true` if refbase object is not a "null ptr"; `false` otherwise. 7353f4cbf05Sopenharmony_ci */ 7363f4cbf05Sopenharmony_ci inline explicit operator bool() const 7373f4cbf05Sopenharmony_ci { 7383f4cbf05Sopenharmony_ci return refs_ != nullptr; 7393f4cbf05Sopenharmony_ci } 7403f4cbf05Sopenharmony_ci 7413f4cbf05Sopenharmony_ci /** 7423f4cbf05Sopenharmony_ci * @brief Dereference operator. 7433f4cbf05Sopenharmony_ci * 7443f4cbf05Sopenharmony_ci * This function will return the object managed by this sptr. 7453f4cbf05Sopenharmony_ci * 7463f4cbf05Sopenharmony_ci * @return Reference to the specific object managed by sptr. 7473f4cbf05Sopenharmony_ci */ 7483f4cbf05Sopenharmony_ci inline T &operator*() const 7493f4cbf05Sopenharmony_ci { 7503f4cbf05Sopenharmony_ci return *refs_; 7513f4cbf05Sopenharmony_ci } 7523f4cbf05Sopenharmony_ci 7533f4cbf05Sopenharmony_ci /** 7543f4cbf05Sopenharmony_ci * @brief Member selection operator. 7553f4cbf05Sopenharmony_ci * 7563f4cbf05Sopenharmony_ci * This function will return the specified member of the object 7573f4cbf05Sopenharmony_ci * managed by this sptr. 7583f4cbf05Sopenharmony_ci */ 7593f4cbf05Sopenharmony_ci inline T *operator->() const 7603f4cbf05Sopenharmony_ci { 7613f4cbf05Sopenharmony_ci return refs_; 7623f4cbf05Sopenharmony_ci } 7633f4cbf05Sopenharmony_ci 7643f4cbf05Sopenharmony_ci /** 7653f4cbf05Sopenharmony_ci * @brief Copy assignment operator with the specified object to be managed. 7663f4cbf05Sopenharmony_ci * And We do not recommend using this interface to create an sptr object. 7673f4cbf05Sopenharmony_ci * Using the interface `sptr::MakeSptr` is better. 7683f4cbf05Sopenharmony_ci * 7693f4cbf05Sopenharmony_ci * @note The original reference will be removed, and a new reference to the 7703f4cbf05Sopenharmony_ci * input object will be established. 7713f4cbf05Sopenharmony_ci * @param other Another object to be managed by this sptr. 7723f4cbf05Sopenharmony_ci */ 7733f4cbf05Sopenharmony_ci sptr<T> &operator=(T *other); 7743f4cbf05Sopenharmony_ci 7753f4cbf05Sopenharmony_ci /** 7763f4cbf05Sopenharmony_ci * @brief Copy assignment operator for sptr with 7773f4cbf05Sopenharmony_ci * the same managed class type (T). 7783f4cbf05Sopenharmony_ci * 7793f4cbf05Sopenharmony_ci * @note The original reference will be removed, and the same object 7803f4cbf05Sopenharmony_ci * with the input sptr object will be managed by this sptr. 7813f4cbf05Sopenharmony_ci * @param other Another sptr object with the same managed class type (T). 7823f4cbf05Sopenharmony_ci */ 7833f4cbf05Sopenharmony_ci sptr<T> &operator=(const sptr<T> &other); 7843f4cbf05Sopenharmony_ci 7853f4cbf05Sopenharmony_ci /** 7863f4cbf05Sopenharmony_ci * @brief Copy assignment operator for wptr with 7873f4cbf05Sopenharmony_ci * the same managed class type (T). 7883f4cbf05Sopenharmony_ci * 7893f4cbf05Sopenharmony_ci * @note The original reference will be removed, and the same object 7903f4cbf05Sopenharmony_ci * with the input wptr object will be managed by this sptr. 7913f4cbf05Sopenharmony_ci * @note If the operation fails, this sptr will turn to be a "null sptr". 7923f4cbf05Sopenharmony_ci * @param other Another wptr object with the same managed class type (T). 7933f4cbf05Sopenharmony_ci */ 7943f4cbf05Sopenharmony_ci sptr<T> &operator=(const wptr<T> &other); 7953f4cbf05Sopenharmony_ci 7963f4cbf05Sopenharmony_ci /** 7973f4cbf05Sopenharmony_ci * @brief Copy assignment operator for sptr with 7983f4cbf05Sopenharmony_ci * a different managed class type (O). 7993f4cbf05Sopenharmony_ci * 8003f4cbf05Sopenharmony_ci * @note The original reference will be removed, and the same object 8013f4cbf05Sopenharmony_ci * with the input sptr object will be managed by this sptr. 8023f4cbf05Sopenharmony_ci * @note This sptr will interpret the managed object as the type (T). 8033f4cbf05Sopenharmony_ci * @param other Another sptr object with a different managed class type (O). 8043f4cbf05Sopenharmony_ci */ 8053f4cbf05Sopenharmony_ci template <typename O> 8063f4cbf05Sopenharmony_ci sptr<T> &operator=(const sptr<O> &other); 8073f4cbf05Sopenharmony_ci 8083f4cbf05Sopenharmony_ci /** 8093f4cbf05Sopenharmony_ci * @brief Equal-to operator between the sptr and raw pointer. 8103f4cbf05Sopenharmony_ci * 8113f4cbf05Sopenharmony_ci * @param other Input raw pointer. 8123f4cbf05Sopenharmony_ci * @return `true` if the sptr points to the same object with input 8133f4cbf05Sopenharmony_ci * raw pointer; `false` otherwise. 8143f4cbf05Sopenharmony_ci */ 8153f4cbf05Sopenharmony_ci bool operator==(const T *other) const; 8163f4cbf05Sopenharmony_ci 8173f4cbf05Sopenharmony_ci /** 8183f4cbf05Sopenharmony_ci * @brief Not-equal-to operator between the sptr and raw pointer. 8193f4cbf05Sopenharmony_ci * 8203f4cbf05Sopenharmony_ci * @param other Input raw pointer. 8213f4cbf05Sopenharmony_ci * @return `true` if the sptr does not point to the same object 8223f4cbf05Sopenharmony_ci * with input raw pointer; `false` otherwise. 8233f4cbf05Sopenharmony_ci */ 8243f4cbf05Sopenharmony_ci inline bool operator!=(const T *other) const 8253f4cbf05Sopenharmony_ci { 8263f4cbf05Sopenharmony_ci return !operator==(other); 8273f4cbf05Sopenharmony_ci } 8283f4cbf05Sopenharmony_ci 8293f4cbf05Sopenharmony_ci /** 8303f4cbf05Sopenharmony_ci * @brief Equal-to operator between the sptr and wptr. 8313f4cbf05Sopenharmony_ci * 8323f4cbf05Sopenharmony_ci * @param other Input wptr. 8333f4cbf05Sopenharmony_ci * @return `true` if the same object is managed by the sptr and wptr; 8343f4cbf05Sopenharmony_ci * `false` otherwise. 8353f4cbf05Sopenharmony_ci */ 8363f4cbf05Sopenharmony_ci bool operator==(const wptr<T> &other) const; 8373f4cbf05Sopenharmony_ci 8383f4cbf05Sopenharmony_ci /** 8393f4cbf05Sopenharmony_ci * @brief Not-equal-to operator between the sptr and wptr. 8403f4cbf05Sopenharmony_ci * 8413f4cbf05Sopenharmony_ci * @param other Input wptr. 8423f4cbf05Sopenharmony_ci * @return `true` if different objects are managed by the sptr and wptr; 8433f4cbf05Sopenharmony_ci * `false` otherwise. 8443f4cbf05Sopenharmony_ci */ 8453f4cbf05Sopenharmony_ci inline bool operator!=(const wptr<T> &other) const 8463f4cbf05Sopenharmony_ci { 8473f4cbf05Sopenharmony_ci return !operator==(other); 8483f4cbf05Sopenharmony_ci } 8493f4cbf05Sopenharmony_ci 8503f4cbf05Sopenharmony_ci /** 8513f4cbf05Sopenharmony_ci * @brief Equal-to operator between two sptrs. 8523f4cbf05Sopenharmony_ci * 8533f4cbf05Sopenharmony_ci * @param other Input sptr. 8543f4cbf05Sopenharmony_ci * @return `true` if the same object is managed by two sptrs; 8553f4cbf05Sopenharmony_ci * `false` otherwise. 8563f4cbf05Sopenharmony_ci */ 8573f4cbf05Sopenharmony_ci bool operator==(const sptr<T> &other) const; 8583f4cbf05Sopenharmony_ci 8593f4cbf05Sopenharmony_ci /** 8603f4cbf05Sopenharmony_ci * @brief Not-equal-to operator between sptrs. 8613f4cbf05Sopenharmony_ci * 8623f4cbf05Sopenharmony_ci * @param other Input sptr. 8633f4cbf05Sopenharmony_ci * @return `true` if different objects are managed by two sptrs; 8643f4cbf05Sopenharmony_ci * `false` otherwise. 8653f4cbf05Sopenharmony_ci */ 8663f4cbf05Sopenharmony_ci inline bool operator!=(const sptr<T> &other) const 8673f4cbf05Sopenharmony_ci { 8683f4cbf05Sopenharmony_ci return !operator==(other); 8693f4cbf05Sopenharmony_ci } 8703f4cbf05Sopenharmony_ci 8713f4cbf05Sopenharmony_ciprivate: 8723f4cbf05Sopenharmony_ci T *refs_ = nullptr; // Raw pointer to the specific managed object 8733f4cbf05Sopenharmony_ci}; 8743f4cbf05Sopenharmony_ci 8753f4cbf05Sopenharmony_citemplate <typename T> 8763f4cbf05Sopenharmony_citemplate <typename... Args> 8773f4cbf05Sopenharmony_cisptr<T> sptr<T>::MakeSptr(Args&&... args) 8783f4cbf05Sopenharmony_ci{ 8793f4cbf05Sopenharmony_ci T *ptr = new T(std::forward<Args>(args)...); 8803f4cbf05Sopenharmony_ci sptr<T> res; 8813f4cbf05Sopenharmony_ci res.ForceSetRefPtr(ptr); 8823f4cbf05Sopenharmony_ci ptr->IncStrongRef(ptr); 8833f4cbf05Sopenharmony_ci return res; 8843f4cbf05Sopenharmony_ci} 8853f4cbf05Sopenharmony_ci 8863f4cbf05Sopenharmony_citemplate <typename T> 8873f4cbf05Sopenharmony_ciinline void sptr<T>::ForceSetRefPtr(T *other) 8883f4cbf05Sopenharmony_ci{ 8893f4cbf05Sopenharmony_ci refs_ = other; 8903f4cbf05Sopenharmony_ci} 8913f4cbf05Sopenharmony_ci 8923f4cbf05Sopenharmony_citemplate <typename T> 8933f4cbf05Sopenharmony_ciinline sptr<T>::sptr() 8943f4cbf05Sopenharmony_ci{ 8953f4cbf05Sopenharmony_ci refs_ = nullptr; 8963f4cbf05Sopenharmony_ci} 8973f4cbf05Sopenharmony_ci 8983f4cbf05Sopenharmony_citemplate <typename T> 8993f4cbf05Sopenharmony_ciinline sptr<T>::sptr(T *other) 9003f4cbf05Sopenharmony_ci{ 9013f4cbf05Sopenharmony_ci refs_ = other; 9023f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 9033f4cbf05Sopenharmony_ci refs_->IncStrongRef(this); 9043f4cbf05Sopenharmony_ci } 9053f4cbf05Sopenharmony_ci} 9063f4cbf05Sopenharmony_ci 9073f4cbf05Sopenharmony_citemplate <typename T> 9083f4cbf05Sopenharmony_ciinline sptr<T>::sptr(const sptr<T> &other) 9093f4cbf05Sopenharmony_ci{ 9103f4cbf05Sopenharmony_ci refs_ = other.GetRefPtr(); 9113f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 9123f4cbf05Sopenharmony_ci refs_->IncStrongRef(this); 9133f4cbf05Sopenharmony_ci } 9143f4cbf05Sopenharmony_ci} 9153f4cbf05Sopenharmony_ci 9163f4cbf05Sopenharmony_citemplate <typename T> 9173f4cbf05Sopenharmony_cisptr<T>::sptr(sptr<T> &&other) 9183f4cbf05Sopenharmony_ci{ 9193f4cbf05Sopenharmony_ci refs_ = other.GetRefPtr(); 9203f4cbf05Sopenharmony_ci other.ForceSetRefPtr(nullptr); 9213f4cbf05Sopenharmony_ci} 9223f4cbf05Sopenharmony_ci 9233f4cbf05Sopenharmony_citemplate <typename T> 9243f4cbf05Sopenharmony_cisptr<T> &sptr<T>::operator=(sptr<T> &&other) 9253f4cbf05Sopenharmony_ci{ 9263f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 9273f4cbf05Sopenharmony_ci refs_->DecStrongRef(this); 9283f4cbf05Sopenharmony_ci } 9293f4cbf05Sopenharmony_ci refs_ = other.GetRefPtr(); 9303f4cbf05Sopenharmony_ci other.ForceSetRefPtr(nullptr); 9313f4cbf05Sopenharmony_ci return *this; 9323f4cbf05Sopenharmony_ci} 9333f4cbf05Sopenharmony_ci 9343f4cbf05Sopenharmony_citemplate <typename T> 9353f4cbf05Sopenharmony_citemplate <typename O> 9363f4cbf05Sopenharmony_cisptr<T>::sptr(const sptr<O> &other) : refs_(other.GetRefPtr()) 9373f4cbf05Sopenharmony_ci{ 9383f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 9393f4cbf05Sopenharmony_ci refs_->IncStrongRef(this); 9403f4cbf05Sopenharmony_ci } 9413f4cbf05Sopenharmony_ci} 9423f4cbf05Sopenharmony_ci 9433f4cbf05Sopenharmony_citemplate <typename T> 9443f4cbf05Sopenharmony_ciinline sptr<T> &sptr<T>::operator=(T *other) 9453f4cbf05Sopenharmony_ci{ 9463f4cbf05Sopenharmony_ci if (other != nullptr) { 9473f4cbf05Sopenharmony_ci other->IncStrongRef(this); 9483f4cbf05Sopenharmony_ci } 9493f4cbf05Sopenharmony_ci 9503f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 9513f4cbf05Sopenharmony_ci refs_->DecStrongRef(this); 9523f4cbf05Sopenharmony_ci } 9533f4cbf05Sopenharmony_ci 9543f4cbf05Sopenharmony_ci refs_ = other; 9553f4cbf05Sopenharmony_ci return *this; 9563f4cbf05Sopenharmony_ci} 9573f4cbf05Sopenharmony_ci 9583f4cbf05Sopenharmony_citemplate <typename T> 9593f4cbf05Sopenharmony_ciinline sptr<T> &sptr<T>::operator=(const sptr<T> &other) 9603f4cbf05Sopenharmony_ci{ 9613f4cbf05Sopenharmony_ci T *otherRef(other.GetRefPtr()); 9623f4cbf05Sopenharmony_ci if (otherRef != nullptr) { 9633f4cbf05Sopenharmony_ci otherRef->IncStrongRef(this); 9643f4cbf05Sopenharmony_ci } 9653f4cbf05Sopenharmony_ci 9663f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 9673f4cbf05Sopenharmony_ci refs_->DecStrongRef(this); 9683f4cbf05Sopenharmony_ci } 9693f4cbf05Sopenharmony_ci 9703f4cbf05Sopenharmony_ci refs_ = otherRef; 9713f4cbf05Sopenharmony_ci return *this; 9723f4cbf05Sopenharmony_ci} 9733f4cbf05Sopenharmony_ci 9743f4cbf05Sopenharmony_citemplate <typename T> 9753f4cbf05Sopenharmony_ciinline sptr<T> &sptr<T>::operator=(const wptr<T> &other) 9763f4cbf05Sopenharmony_ci{ 9773f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 9783f4cbf05Sopenharmony_ci refs_->DecStrongRef(this); 9793f4cbf05Sopenharmony_ci } 9803f4cbf05Sopenharmony_ci if ((other != nullptr) && other.AttemptIncStrongRef(this)) { 9813f4cbf05Sopenharmony_ci refs_ = other.GetRefPtr(); 9823f4cbf05Sopenharmony_ci } else { 9833f4cbf05Sopenharmony_ci refs_ = nullptr; 9843f4cbf05Sopenharmony_ci } 9853f4cbf05Sopenharmony_ci 9863f4cbf05Sopenharmony_ci return *this; 9873f4cbf05Sopenharmony_ci} 9883f4cbf05Sopenharmony_ci 9893f4cbf05Sopenharmony_citemplate <typename T> 9903f4cbf05Sopenharmony_citemplate <typename O> 9913f4cbf05Sopenharmony_cisptr<T> &sptr<T>::operator=(const sptr<O> &other) 9923f4cbf05Sopenharmony_ci{ 9933f4cbf05Sopenharmony_ci T *otherRef(other.GetRefPtr()); 9943f4cbf05Sopenharmony_ci if (otherRef != nullptr) { 9953f4cbf05Sopenharmony_ci otherRef->IncStrongRef(this); 9963f4cbf05Sopenharmony_ci } 9973f4cbf05Sopenharmony_ci 9983f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 9993f4cbf05Sopenharmony_ci refs_->DecStrongRef(this); 10003f4cbf05Sopenharmony_ci } 10013f4cbf05Sopenharmony_ci 10023f4cbf05Sopenharmony_ci refs_ = otherRef; 10033f4cbf05Sopenharmony_ci return *this; 10043f4cbf05Sopenharmony_ci} 10053f4cbf05Sopenharmony_ci 10063f4cbf05Sopenharmony_citemplate <typename T> 10073f4cbf05Sopenharmony_ciinline bool sptr<T>::operator==(const T *other) const 10083f4cbf05Sopenharmony_ci{ 10093f4cbf05Sopenharmony_ci return other == refs_; 10103f4cbf05Sopenharmony_ci} 10113f4cbf05Sopenharmony_ci 10123f4cbf05Sopenharmony_citemplate <typename T> 10133f4cbf05Sopenharmony_ciinline bool sptr<T>::operator==(const wptr<T> &other) const 10143f4cbf05Sopenharmony_ci{ 10153f4cbf05Sopenharmony_ci return refs_ == other.GetRefPtr(); 10163f4cbf05Sopenharmony_ci} 10173f4cbf05Sopenharmony_ci 10183f4cbf05Sopenharmony_citemplate <typename T> 10193f4cbf05Sopenharmony_ciinline bool sptr<T>::operator==(const sptr<T> &other) const 10203f4cbf05Sopenharmony_ci{ 10213f4cbf05Sopenharmony_ci return refs_ == other.GetRefPtr(); 10223f4cbf05Sopenharmony_ci} 10233f4cbf05Sopenharmony_ci 10243f4cbf05Sopenharmony_citemplate<typename T> 10253f4cbf05Sopenharmony_civoid sptr<T>::clear() 10263f4cbf05Sopenharmony_ci{ 10273f4cbf05Sopenharmony_ci if (refs_) { 10283f4cbf05Sopenharmony_ci refs_->DecStrongRef(this); 10293f4cbf05Sopenharmony_ci refs_ = 0; 10303f4cbf05Sopenharmony_ci } 10313f4cbf05Sopenharmony_ci} 10323f4cbf05Sopenharmony_ci 10333f4cbf05Sopenharmony_citemplate <typename T> 10343f4cbf05Sopenharmony_ciinline sptr<T>::~sptr() 10353f4cbf05Sopenharmony_ci{ 10363f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 10373f4cbf05Sopenharmony_ci refs_->DecStrongRef(this); 10383f4cbf05Sopenharmony_ci } 10393f4cbf05Sopenharmony_ci} 10403f4cbf05Sopenharmony_ci 10413f4cbf05Sopenharmony_citemplate <typename T> 10423f4cbf05Sopenharmony_ciinline sptr<T>::sptr(WeakRefCounter *p, bool /* force */) 10433f4cbf05Sopenharmony_ci{ 10443f4cbf05Sopenharmony_ci if ((p != nullptr) && p->AttemptIncStrongRef(this)) { 10453f4cbf05Sopenharmony_ci refs_ = reinterpret_cast<T *>(p->GetRefPtr()); 10463f4cbf05Sopenharmony_ci } else { 10473f4cbf05Sopenharmony_ci refs_ = nullptr; 10483f4cbf05Sopenharmony_ci } 10493f4cbf05Sopenharmony_ci} 10503f4cbf05Sopenharmony_ci 10513f4cbf05Sopenharmony_ci/** 10523f4cbf05Sopenharmony_ci * @ingroup SmartPointer 10533f4cbf05Sopenharmony_ci * @brief Weak reference smart pointer to a RefBase object 10543f4cbf05Sopenharmony_ci * (or an object of its subclass). 10553f4cbf05Sopenharmony_ci * 10563f4cbf05Sopenharmony_ci * A weak reference indirectly references the RefBase object 10573f4cbf05Sopenharmony_ci * and directly references the WeakRefCounter object. 10583f4cbf05Sopenharmony_ci * 10593f4cbf05Sopenharmony_ci * @tparam T Specific class type managed by wptr. 10603f4cbf05Sopenharmony_ci * This class must inherit from RefBase. 10613f4cbf05Sopenharmony_ci */ 10623f4cbf05Sopenharmony_citemplate <typename T> 10633f4cbf05Sopenharmony_ciclass wptr { 10643f4cbf05Sopenharmony_ci template <typename O> 10653f4cbf05Sopenharmony_ci friend class wptr; 10663f4cbf05Sopenharmony_ci 10673f4cbf05Sopenharmony_cipublic: 10683f4cbf05Sopenharmony_ci wptr(); 10693f4cbf05Sopenharmony_ci 10703f4cbf05Sopenharmony_ci /** 10713f4cbf05Sopenharmony_ci * @brief Constructor with the specified object to be managed. 10723f4cbf05Sopenharmony_ci * 10733f4cbf05Sopenharmony_ci * This function will create WeakRefCounter object for `other` 10743f4cbf05Sopenharmony_ci * and set the count of weak references to 1. 10753f4cbf05Sopenharmony_ci * 10763f4cbf05Sopenharmony_ci * @note A WeakRefCounter object will not be created if `other` 10773f4cbf05Sopenharmony_ci * is a `nullptr`. 10783f4cbf05Sopenharmony_ci * 10793f4cbf05Sopenharmony_ci * @param other Object to be managed by wptr. 10803f4cbf05Sopenharmony_ci */ 10813f4cbf05Sopenharmony_ci wptr(T *other); 10823f4cbf05Sopenharmony_ci 10833f4cbf05Sopenharmony_ci /** 10843f4cbf05Sopenharmony_ci * @brief Copy constructor for wptr with the same managed class type (T). 10853f4cbf05Sopenharmony_ci * 10863f4cbf05Sopenharmony_ci * This function will share the WeakRefCounter object of `other` with this 10873f4cbf05Sopenharmony_ci * wptr and set the count of weak references properly. 10883f4cbf05Sopenharmony_ci * 10893f4cbf05Sopenharmony_ci * @param other Another wptr with the same managed class type (T). 10903f4cbf05Sopenharmony_ci */ 10913f4cbf05Sopenharmony_ci wptr(const wptr<T> &other); 10923f4cbf05Sopenharmony_ci 10933f4cbf05Sopenharmony_ci /** 10943f4cbf05Sopenharmony_ci * @brief Copy constructor for sptr with the same managed class type (T). 10953f4cbf05Sopenharmony_ci * 10963f4cbf05Sopenharmony_ci * This function will create a WeakRefCounter object for the managed 10973f4cbf05Sopenharmony_ci * object of `other`, and set the count of weak references properly. 10983f4cbf05Sopenharmony_ci * 10993f4cbf05Sopenharmony_ci * @param other Another sptr with the same managed class type (T). 11003f4cbf05Sopenharmony_ci * @tparam T Specific class type managed by `other`. 11013f4cbf05Sopenharmony_ci */ 11023f4cbf05Sopenharmony_ci wptr(const sptr<T> &other); 11033f4cbf05Sopenharmony_ci 11043f4cbf05Sopenharmony_ci /** 11053f4cbf05Sopenharmony_ci * @brief Copy constructor for wptr with a different managed class type (O). 11063f4cbf05Sopenharmony_ci * 11073f4cbf05Sopenharmony_ci * This function is the same as wptr<T>::wptr(const wptr<T> &other). 11083f4cbf05Sopenharmony_ci * 11093f4cbf05Sopenharmony_ci * @tparam O Class type managed by `other`. 11103f4cbf05Sopenharmony_ci * @param other Another wptr with a different managed class type (O). 11113f4cbf05Sopenharmony_ci * @tparam T Specific class type managed by `other`. 11123f4cbf05Sopenharmony_ci */ 11133f4cbf05Sopenharmony_ci template <typename O> 11143f4cbf05Sopenharmony_ci wptr(const wptr<O> &other); 11153f4cbf05Sopenharmony_ci 11163f4cbf05Sopenharmony_ci /** 11173f4cbf05Sopenharmony_ci * @brief Copy constructor for sptr with a different managed class type (O). 11183f4cbf05Sopenharmony_ci * 11193f4cbf05Sopenharmony_ci * This function is the same as wptr<T>::wptr(const sptr<T> &other). 11203f4cbf05Sopenharmony_ci * 11213f4cbf05Sopenharmony_ci * @param other Another sptr with the same managed class type (O). 11223f4cbf05Sopenharmony_ci * @tparam T Specific class type managed by `other`. 11233f4cbf05Sopenharmony_ci */ 11243f4cbf05Sopenharmony_ci template <typename O> 11253f4cbf05Sopenharmony_ci wptr(const sptr<O> &other); 11263f4cbf05Sopenharmony_ci 11273f4cbf05Sopenharmony_ci /** 11283f4cbf05Sopenharmony_ci * @brief Copy assignment operator with the specified object to be managed. 11293f4cbf05Sopenharmony_ci * 11303f4cbf05Sopenharmony_ci * @note The current wptr will unbind the original WeakRefCounter object, 11313f4cbf05Sopenharmony_ci * create a new WeakRefCounter object, and then set the count of weak 11323f4cbf05Sopenharmony_ci * references properly. 11333f4cbf05Sopenharmony_ci * @param other Another object to be managed by this wptr. 11343f4cbf05Sopenharmony_ci */ 11353f4cbf05Sopenharmony_ci wptr<T> &operator=(T *other); 11363f4cbf05Sopenharmony_ci 11373f4cbf05Sopenharmony_ci /** 11383f4cbf05Sopenharmony_ci * @brief Copy assignment operator with the specified object to be managed. 11393f4cbf05Sopenharmony_ci * 11403f4cbf05Sopenharmony_ci * @note Same with wptr<T> &operator=(T *other), but a pointer type casting 11413f4cbf05Sopenharmony_ci * which will not affect the type of `*other` is processed. 11423f4cbf05Sopenharmony_ci * @tparam O Specific class type managed by `other`. 11433f4cbf05Sopenharmony_ci * @param other Another object to be managed by this wptr. 11443f4cbf05Sopenharmony_ci * 11453f4cbf05Sopenharmony_ci */ 11463f4cbf05Sopenharmony_ci template <typename O> 11473f4cbf05Sopenharmony_ci wptr<T> &operator=(O *other); 11483f4cbf05Sopenharmony_ci 11493f4cbf05Sopenharmony_ci /** 11503f4cbf05Sopenharmony_ci * @brief Copy assignment operator for wptr with the same managed class 11513f4cbf05Sopenharmony_ci * type (T). 11523f4cbf05Sopenharmony_ci * 11533f4cbf05Sopenharmony_ci * @note The current wptr will unbind the original WeakRefCounter object, 11543f4cbf05Sopenharmony_ci * share the WeakRefCounter object with `other`, and then set the count of 11553f4cbf05Sopenharmony_ci * weak references properly. 11563f4cbf05Sopenharmony_ci * @param other Another wptr object. Objects managed by it will also be 11573f4cbf05Sopenharmony_ci * managed by this wptr. 11583f4cbf05Sopenharmony_ci */ 11593f4cbf05Sopenharmony_ci wptr<T> &operator=(const wptr<T> &other); 11603f4cbf05Sopenharmony_ci 11613f4cbf05Sopenharmony_ci /** 11623f4cbf05Sopenharmony_ci * @brief Copy assignment operator for sptr with the same managed class 11633f4cbf05Sopenharmony_ci * type (T). 11643f4cbf05Sopenharmony_ci * 11653f4cbf05Sopenharmony_ci * @note The current wptr will unbind the original WeakRefCounter object, 11663f4cbf05Sopenharmony_ci * create a new WeakRefCounter object, and then set the count of weak 11673f4cbf05Sopenharmony_ci * references properly. 11683f4cbf05Sopenharmony_ci * @param other A sptr object. Objects managed by it will also be 11693f4cbf05Sopenharmony_ci * managed by this wptr. 11703f4cbf05Sopenharmony_ci */ 11713f4cbf05Sopenharmony_ci wptr<T> &operator=(const sptr<T> &other); 11723f4cbf05Sopenharmony_ci 11733f4cbf05Sopenharmony_ci /** 11743f4cbf05Sopenharmony_ci * @brief Copy assignment operator for wptr with a different managed class 11753f4cbf05Sopenharmony_ci * type (O). 11763f4cbf05Sopenharmony_ci * 11773f4cbf05Sopenharmony_ci * @note This function is the same as wptr<T> &operator=(const wptr<T> &). 11783f4cbf05Sopenharmony_ci * Note that no cast here is processed. 11793f4cbf05Sopenharmony_ci * @param other An wptr object. Objects managed by it will also be 11803f4cbf05Sopenharmony_ci * managed by this wptr. 11813f4cbf05Sopenharmony_ci * @tparam O Specific class type managed by `other`. 11823f4cbf05Sopenharmony_ci */ 11833f4cbf05Sopenharmony_ci template <typename O> 11843f4cbf05Sopenharmony_ci wptr<T> &operator=(const wptr<O> &other); 11853f4cbf05Sopenharmony_ci 11863f4cbf05Sopenharmony_ci /** 11873f4cbf05Sopenharmony_ci * @brief Copy assignment operator for sptr with a different managed class 11883f4cbf05Sopenharmony_ci * type (O). 11893f4cbf05Sopenharmony_ci * 11903f4cbf05Sopenharmony_ci * @note This function is the same as 11913f4cbf05Sopenharmony_ci * wptr<T> &wptr<T>::operator=(const sptr<T> &). 11923f4cbf05Sopenharmony_ci * Note that no cast here is processed. 11933f4cbf05Sopenharmony_ci * @param other An sptr object. Objects managed by it will also be 11943f4cbf05Sopenharmony_ci * managed by this wptr. 11953f4cbf05Sopenharmony_ci * @tparam O Specific class type managed by `other`. 11963f4cbf05Sopenharmony_ci */ 11973f4cbf05Sopenharmony_ci template <typename O> 11983f4cbf05Sopenharmony_ci wptr<T> &operator=(const sptr<O> &other); 11993f4cbf05Sopenharmony_ci 12003f4cbf05Sopenharmony_ci /** 12013f4cbf05Sopenharmony_ci * @brief Dereference operator. 12023f4cbf05Sopenharmony_ci * 12033f4cbf05Sopenharmony_ci * This function will return the object managed by this wptr. 12043f4cbf05Sopenharmony_ci * 12053f4cbf05Sopenharmony_ci * @return Specific object managed by wptr. 12063f4cbf05Sopenharmony_ci */ 12073f4cbf05Sopenharmony_ci inline T &operator*() const 12083f4cbf05Sopenharmony_ci { 12093f4cbf05Sopenharmony_ci return *GetRefPtr(); 12103f4cbf05Sopenharmony_ci } 12113f4cbf05Sopenharmony_ci 12123f4cbf05Sopenharmony_ci /** 12133f4cbf05Sopenharmony_ci * @brief Member selection operator. 12143f4cbf05Sopenharmony_ci * 12153f4cbf05Sopenharmony_ci * This function will return the specified object member managed 12163f4cbf05Sopenharmony_ci * by this wptr. 12173f4cbf05Sopenharmony_ci */ 12183f4cbf05Sopenharmony_ci inline T *operator->() const 12193f4cbf05Sopenharmony_ci { 12203f4cbf05Sopenharmony_ci return reinterpret_cast<T *>(refs_->GetRefPtr()); 12213f4cbf05Sopenharmony_ci } 12223f4cbf05Sopenharmony_ci 12233f4cbf05Sopenharmony_ci /** 12243f4cbf05Sopenharmony_ci * @brief Equal-to operator between the wptr and raw pointer. 12253f4cbf05Sopenharmony_ci * 12263f4cbf05Sopenharmony_ci * @param other Input raw pointer. 12273f4cbf05Sopenharmony_ci * @return `true` if two pointers have the same value; `false` otherwise. 12283f4cbf05Sopenharmony_ci */ 12293f4cbf05Sopenharmony_ci bool operator==(const T *other) const; 12303f4cbf05Sopenharmony_ci 12313f4cbf05Sopenharmony_ci /** 12323f4cbf05Sopenharmony_ci * @brief Not-equal-to operator between the wptr and raw pointer. 12333f4cbf05Sopenharmony_ci * 12343f4cbf05Sopenharmony_ci * @param other Input raw pointer. 12353f4cbf05Sopenharmony_ci * @return `true` if two pointers have different values; `false` otherwise. 12363f4cbf05Sopenharmony_ci */ 12373f4cbf05Sopenharmony_ci inline bool operator!=(const T *other) const 12383f4cbf05Sopenharmony_ci { 12393f4cbf05Sopenharmony_ci return !operator==(other); 12403f4cbf05Sopenharmony_ci }; 12413f4cbf05Sopenharmony_ci 12423f4cbf05Sopenharmony_ci /** 12433f4cbf05Sopenharmony_ci * @brief Equal-to operator between two wptrs. 12443f4cbf05Sopenharmony_ci * 12453f4cbf05Sopenharmony_ci * @param other Input reference to a wptr object. 12463f4cbf05Sopenharmony_ci * @return `true` if two pointers have the same value; `false` otherwise. 12473f4cbf05Sopenharmony_ci */ 12483f4cbf05Sopenharmony_ci bool operator==(const wptr<T> &other) const; 12493f4cbf05Sopenharmony_ci 12503f4cbf05Sopenharmony_ci /** 12513f4cbf05Sopenharmony_ci * @brief Not-equal-to operator between two wptrs. 12523f4cbf05Sopenharmony_ci * 12533f4cbf05Sopenharmony_ci * @param other Input reference to a wptr object. 12543f4cbf05Sopenharmony_ci * @return `true` if two pointers have different values; `false` otherwise. 12553f4cbf05Sopenharmony_ci */ 12563f4cbf05Sopenharmony_ci inline bool operator!=(const wptr<T> &other) const 12573f4cbf05Sopenharmony_ci { 12583f4cbf05Sopenharmony_ci return !operator==(other); 12593f4cbf05Sopenharmony_ci } 12603f4cbf05Sopenharmony_ci 12613f4cbf05Sopenharmony_ci /** 12623f4cbf05Sopenharmony_ci * @brief Equal-to operator between the wptr and input sptr object. 12633f4cbf05Sopenharmony_ci * 12643f4cbf05Sopenharmony_ci * @param other Input reference to an sptr object. 12653f4cbf05Sopenharmony_ci * @return true` if two pointers have the same value; `false` otherwise. 12663f4cbf05Sopenharmony_ci */ 12673f4cbf05Sopenharmony_ci bool operator==(const sptr<T> &other) const; 12683f4cbf05Sopenharmony_ci 12693f4cbf05Sopenharmony_ci /** 12703f4cbf05Sopenharmony_ci * @brief Not-equal-to operator between the wptr and input sptr object. 12713f4cbf05Sopenharmony_ci * 12723f4cbf05Sopenharmony_ci * @param other Input reference to an sptr object. 12733f4cbf05Sopenharmony_ci * @return `true` if two pointers have different values; `false` otherwise. 12743f4cbf05Sopenharmony_ci */ 12753f4cbf05Sopenharmony_ci inline bool operator!=(const sptr<T> &other) const 12763f4cbf05Sopenharmony_ci { 12773f4cbf05Sopenharmony_ci return !operator==(other); 12783f4cbf05Sopenharmony_ci } 12793f4cbf05Sopenharmony_ci 12803f4cbf05Sopenharmony_ci /** 12813f4cbf05Sopenharmony_ci * @brief Gets the pointer to the RefBase object. 12823f4cbf05Sopenharmony_ci * 12833f4cbf05Sopenharmony_ci * @return Raw pointer to the RefBase object. 12843f4cbf05Sopenharmony_ci * @note `nullptr` will be returned if the managed object has been 12853f4cbf05Sopenharmony_ci * deallocated. 12863f4cbf05Sopenharmony_ci */ 12873f4cbf05Sopenharmony_ci T *GetRefPtr() const; 12883f4cbf05Sopenharmony_ci 12893f4cbf05Sopenharmony_ci /** 12903f4cbf05Sopenharmony_ci * @brief Gets the count of weak references in a WeakRefCounter object. 12913f4cbf05Sopenharmony_ci * 12923f4cbf05Sopenharmony_ci * The value indicates how many wptrs share the same WeakRefCounter object. 12933f4cbf05Sopenharmony_ci * 12943f4cbf05Sopenharmony_ci * @return Count of weak references. 12953f4cbf05Sopenharmony_ci * @note Only for test. 12963f4cbf05Sopenharmony_ci */ 12973f4cbf05Sopenharmony_ci inline int GetWeakRefCount() const 12983f4cbf05Sopenharmony_ci { 12993f4cbf05Sopenharmony_ci return refs_->GetWeakRefCount(); 13003f4cbf05Sopenharmony_ci } 13013f4cbf05Sopenharmony_ci 13023f4cbf05Sopenharmony_ci /** 13033f4cbf05Sopenharmony_ci * @brief Attempts to increment the count of strong references in 13043f4cbf05Sopenharmony_ci * the managed object. 13053f4cbf05Sopenharmony_ci * 13063f4cbf05Sopenharmony_ci * @return `true` if the increment is successful; `false` otherwise. 13073f4cbf05Sopenharmony_ci * @note Avoid using this function independently. Use `promote()` instead. 13083f4cbf05Sopenharmony_ci */ 13093f4cbf05Sopenharmony_ci inline bool AttemptIncStrongRef(const void *objectId) const 13103f4cbf05Sopenharmony_ci { 13113f4cbf05Sopenharmony_ci return refs_->AttemptIncStrongRef(objectId); 13123f4cbf05Sopenharmony_ci } 13133f4cbf05Sopenharmony_ci 13143f4cbf05Sopenharmony_ci /** 13153f4cbf05Sopenharmony_ci * @brief Promotes a wptr to an sptr. 13163f4cbf05Sopenharmony_ci * 13173f4cbf05Sopenharmony_ci * This function will create an sptr object based on the object 13183f4cbf05Sopenharmony_ci * managed by this wptr. 13193f4cbf05Sopenharmony_ci * 13203f4cbf05Sopenharmony_ci * @note The original weak reference will be retained. 13213f4cbf05Sopenharmony_ci * If the promotion fails, a "null sptr" will be returned. 13223f4cbf05Sopenharmony_ci */ 13233f4cbf05Sopenharmony_ci const sptr<T> promote() const; 13243f4cbf05Sopenharmony_ci 13253f4cbf05Sopenharmony_ci ~wptr(); 13263f4cbf05Sopenharmony_ci 13273f4cbf05Sopenharmony_ciprivate: 13283f4cbf05Sopenharmony_ci WeakRefCounter *refs_ = nullptr; // Pointer to the corresponding WeakRefCounter object 13293f4cbf05Sopenharmony_ci}; 13303f4cbf05Sopenharmony_ci 13313f4cbf05Sopenharmony_citemplate <typename T> 13323f4cbf05Sopenharmony_ciinline T *wptr<T>::GetRefPtr() const 13333f4cbf05Sopenharmony_ci{ 13343f4cbf05Sopenharmony_ci return (refs_ != nullptr) ? reinterpret_cast<T *>(refs_->GetRefPtr()) : nullptr; 13353f4cbf05Sopenharmony_ci} 13363f4cbf05Sopenharmony_ci 13373f4cbf05Sopenharmony_citemplate <typename T> 13383f4cbf05Sopenharmony_ciwptr<T>::wptr() 13393f4cbf05Sopenharmony_ci{ 13403f4cbf05Sopenharmony_ci refs_ = nullptr; 13413f4cbf05Sopenharmony_ci} 13423f4cbf05Sopenharmony_ci 13433f4cbf05Sopenharmony_citemplate <typename T> 13443f4cbf05Sopenharmony_ciwptr<T>::wptr(T *other) 13453f4cbf05Sopenharmony_ci{ 13463f4cbf05Sopenharmony_ci if (other != nullptr) { 13473f4cbf05Sopenharmony_ci refs_ = other->CreateWeakRef(other); 13483f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 13493f4cbf05Sopenharmony_ci refs_->IncWeakRefCount(this); 13503f4cbf05Sopenharmony_ci } 13513f4cbf05Sopenharmony_ci } else { 13523f4cbf05Sopenharmony_ci refs_ = nullptr; 13533f4cbf05Sopenharmony_ci } 13543f4cbf05Sopenharmony_ci} 13553f4cbf05Sopenharmony_ci 13563f4cbf05Sopenharmony_citemplate <typename T> 13573f4cbf05Sopenharmony_ciwptr<T>::wptr(const wptr<T> &other) 13583f4cbf05Sopenharmony_ci{ 13593f4cbf05Sopenharmony_ci refs_ = other.refs_; 13603f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 13613f4cbf05Sopenharmony_ci refs_->IncWeakRefCount(this); 13623f4cbf05Sopenharmony_ci } 13633f4cbf05Sopenharmony_ci} 13643f4cbf05Sopenharmony_ci 13653f4cbf05Sopenharmony_citemplate <typename T> 13663f4cbf05Sopenharmony_ciwptr<T>::wptr(const sptr<T> &other) 13673f4cbf05Sopenharmony_ci{ 13683f4cbf05Sopenharmony_ci if (other.GetRefPtr() != nullptr) { 13693f4cbf05Sopenharmony_ci refs_ = other->CreateWeakRef(other.GetRefPtr()); 13703f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 13713f4cbf05Sopenharmony_ci refs_->IncWeakRefCount(this); 13723f4cbf05Sopenharmony_ci } 13733f4cbf05Sopenharmony_ci } 13743f4cbf05Sopenharmony_ci} 13753f4cbf05Sopenharmony_ci 13763f4cbf05Sopenharmony_citemplate <typename T> 13773f4cbf05Sopenharmony_citemplate <typename O> 13783f4cbf05Sopenharmony_ciwptr<T>::wptr(const wptr<O> &other) 13793f4cbf05Sopenharmony_ci{ 13803f4cbf05Sopenharmony_ci refs_ = other.refs_; 13813f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 13823f4cbf05Sopenharmony_ci refs_->IncWeakRefCount(this); 13833f4cbf05Sopenharmony_ci } 13843f4cbf05Sopenharmony_ci} 13853f4cbf05Sopenharmony_ci 13863f4cbf05Sopenharmony_citemplate <typename T> 13873f4cbf05Sopenharmony_citemplate <typename O> 13883f4cbf05Sopenharmony_ciwptr<T>::wptr(const sptr<O> &other) 13893f4cbf05Sopenharmony_ci{ 13903f4cbf05Sopenharmony_ci if (other.GetRefPtr() != nullptr) { 13913f4cbf05Sopenharmony_ci refs_ = other->CreateWeakRef(other.GetRefPtr()); 13923f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 13933f4cbf05Sopenharmony_ci refs_->IncWeakRefCount(this); 13943f4cbf05Sopenharmony_ci } 13953f4cbf05Sopenharmony_ci } 13963f4cbf05Sopenharmony_ci} 13973f4cbf05Sopenharmony_ci 13983f4cbf05Sopenharmony_citemplate <typename T> 13993f4cbf05Sopenharmony_ciwptr<T> &wptr<T>::operator=(T *other) 14003f4cbf05Sopenharmony_ci{ 14013f4cbf05Sopenharmony_ci WeakRefCounter *newWeakRef = nullptr; 14023f4cbf05Sopenharmony_ci if (other != nullptr) { 14033f4cbf05Sopenharmony_ci newWeakRef = other->CreateWeakRef(other); 14043f4cbf05Sopenharmony_ci if (newWeakRef != nullptr) { 14053f4cbf05Sopenharmony_ci newWeakRef->IncWeakRefCount(this); 14063f4cbf05Sopenharmony_ci } 14073f4cbf05Sopenharmony_ci } 14083f4cbf05Sopenharmony_ci 14093f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 14103f4cbf05Sopenharmony_ci refs_->DecWeakRefCount(this); 14113f4cbf05Sopenharmony_ci } 14123f4cbf05Sopenharmony_ci 14133f4cbf05Sopenharmony_ci refs_ = newWeakRef; 14143f4cbf05Sopenharmony_ci return *this; 14153f4cbf05Sopenharmony_ci} 14163f4cbf05Sopenharmony_ci 14173f4cbf05Sopenharmony_citemplate <typename T> 14183f4cbf05Sopenharmony_citemplate <typename O> 14193f4cbf05Sopenharmony_ciwptr<T> &wptr<T>::operator=(O *other) 14203f4cbf05Sopenharmony_ci{ 14213f4cbf05Sopenharmony_ci T *object = reinterpret_cast<T *>(other); 14223f4cbf05Sopenharmony_ci WeakRefCounter *newWeakRef = nullptr; 14233f4cbf05Sopenharmony_ci if (object != nullptr) { 14243f4cbf05Sopenharmony_ci newWeakRef = object->CreateWeakRef(object); 14253f4cbf05Sopenharmony_ci if (newWeakRef != nullptr) { 14263f4cbf05Sopenharmony_ci newWeakRef->IncWeakRefCount(this); 14273f4cbf05Sopenharmony_ci } 14283f4cbf05Sopenharmony_ci } 14293f4cbf05Sopenharmony_ci 14303f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 14313f4cbf05Sopenharmony_ci refs_->DecWeakRefCount(this); 14323f4cbf05Sopenharmony_ci } 14333f4cbf05Sopenharmony_ci 14343f4cbf05Sopenharmony_ci refs_ = newWeakRef; 14353f4cbf05Sopenharmony_ci return *this; 14363f4cbf05Sopenharmony_ci} 14373f4cbf05Sopenharmony_ci 14383f4cbf05Sopenharmony_citemplate <typename T> 14393f4cbf05Sopenharmony_ciinline wptr<T> &wptr<T>::operator=(const wptr<T> &other) 14403f4cbf05Sopenharmony_ci{ 14413f4cbf05Sopenharmony_ci if (other.refs_ != nullptr) { 14423f4cbf05Sopenharmony_ci other.refs_->IncWeakRefCount(this); 14433f4cbf05Sopenharmony_ci } 14443f4cbf05Sopenharmony_ci 14453f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 14463f4cbf05Sopenharmony_ci refs_->DecWeakRefCount(this); 14473f4cbf05Sopenharmony_ci } 14483f4cbf05Sopenharmony_ci 14493f4cbf05Sopenharmony_ci refs_ = other.refs_; 14503f4cbf05Sopenharmony_ci return *this; 14513f4cbf05Sopenharmony_ci} 14523f4cbf05Sopenharmony_ci 14533f4cbf05Sopenharmony_citemplate <typename T> 14543f4cbf05Sopenharmony_ciinline wptr<T> &wptr<T>::operator=(const sptr<T> &other) 14553f4cbf05Sopenharmony_ci{ 14563f4cbf05Sopenharmony_ci WeakRefCounter *newWeakRef = nullptr; 14573f4cbf05Sopenharmony_ci if (other.GetRefPtr() != nullptr) { 14583f4cbf05Sopenharmony_ci newWeakRef = other->CreateWeakRef(other.GetRefPtr()); 14593f4cbf05Sopenharmony_ci if (newWeakRef != nullptr) { 14603f4cbf05Sopenharmony_ci newWeakRef->IncWeakRefCount(this); 14613f4cbf05Sopenharmony_ci } 14623f4cbf05Sopenharmony_ci } 14633f4cbf05Sopenharmony_ci 14643f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 14653f4cbf05Sopenharmony_ci refs_->DecWeakRefCount(this); 14663f4cbf05Sopenharmony_ci } 14673f4cbf05Sopenharmony_ci 14683f4cbf05Sopenharmony_ci refs_ = newWeakRef; 14693f4cbf05Sopenharmony_ci return *this; 14703f4cbf05Sopenharmony_ci} 14713f4cbf05Sopenharmony_ci 14723f4cbf05Sopenharmony_citemplate <typename T> 14733f4cbf05Sopenharmony_citemplate <typename O> 14743f4cbf05Sopenharmony_ciwptr<T> &wptr<T>::operator=(const wptr<O> &other) 14753f4cbf05Sopenharmony_ci{ 14763f4cbf05Sopenharmony_ci if (other.refs_ != nullptr) { 14773f4cbf05Sopenharmony_ci other.refs_->IncWeakRefCount(this); 14783f4cbf05Sopenharmony_ci } 14793f4cbf05Sopenharmony_ci 14803f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 14813f4cbf05Sopenharmony_ci refs_->DecWeakRefCount(this); 14823f4cbf05Sopenharmony_ci } 14833f4cbf05Sopenharmony_ci 14843f4cbf05Sopenharmony_ci refs_ = other.refs_; 14853f4cbf05Sopenharmony_ci return *this; 14863f4cbf05Sopenharmony_ci} 14873f4cbf05Sopenharmony_ci 14883f4cbf05Sopenharmony_citemplate <typename T> 14893f4cbf05Sopenharmony_citemplate <typename O> 14903f4cbf05Sopenharmony_ciwptr<T> &wptr<T>::operator=(const sptr<O> &other) 14913f4cbf05Sopenharmony_ci{ 14923f4cbf05Sopenharmony_ci WeakRefCounter *newWeakRef = nullptr; 14933f4cbf05Sopenharmony_ci if (other.GetRefPtr() != nullptr) { 14943f4cbf05Sopenharmony_ci newWeakRef = other->CreateWeakRef(other.GetRefPtr()); 14953f4cbf05Sopenharmony_ci if (newWeakRef != nullptr) { 14963f4cbf05Sopenharmony_ci newWeakRef->IncWeakRefCount(this); 14973f4cbf05Sopenharmony_ci } 14983f4cbf05Sopenharmony_ci } 14993f4cbf05Sopenharmony_ci 15003f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 15013f4cbf05Sopenharmony_ci refs_->DecWeakRefCount(this); 15023f4cbf05Sopenharmony_ci } 15033f4cbf05Sopenharmony_ci 15043f4cbf05Sopenharmony_ci refs_ = newWeakRef; 15053f4cbf05Sopenharmony_ci return *this; 15063f4cbf05Sopenharmony_ci} 15073f4cbf05Sopenharmony_ci 15083f4cbf05Sopenharmony_citemplate <typename T> 15093f4cbf05Sopenharmony_ciinline bool wptr<T>::operator==(const T *other) const 15103f4cbf05Sopenharmony_ci{ 15113f4cbf05Sopenharmony_ci return GetRefPtr() == other; 15123f4cbf05Sopenharmony_ci} 15133f4cbf05Sopenharmony_ci 15143f4cbf05Sopenharmony_citemplate <typename T> 15153f4cbf05Sopenharmony_ciinline bool wptr<T>::operator==(const wptr<T> &other) const 15163f4cbf05Sopenharmony_ci{ 15173f4cbf05Sopenharmony_ci return GetRefPtr() == other.GetRefPtr(); 15183f4cbf05Sopenharmony_ci} 15193f4cbf05Sopenharmony_ci 15203f4cbf05Sopenharmony_citemplate <typename T> 15213f4cbf05Sopenharmony_ciinline bool wptr<T>::operator==(const sptr<T> &other) const 15223f4cbf05Sopenharmony_ci{ 15233f4cbf05Sopenharmony_ci return GetRefPtr() == other.GetRefPtr(); 15243f4cbf05Sopenharmony_ci} 15253f4cbf05Sopenharmony_ci 15263f4cbf05Sopenharmony_citemplate <typename T> 15273f4cbf05Sopenharmony_ciinline const sptr<T> wptr<T>::promote() const 15283f4cbf05Sopenharmony_ci{ 15293f4cbf05Sopenharmony_ci return sptr<T>(refs_, true); 15303f4cbf05Sopenharmony_ci} 15313f4cbf05Sopenharmony_ci 15323f4cbf05Sopenharmony_citemplate <typename T> 15333f4cbf05Sopenharmony_ciinline wptr<T>::~wptr() 15343f4cbf05Sopenharmony_ci{ 15353f4cbf05Sopenharmony_ci if (refs_ != nullptr) { 15363f4cbf05Sopenharmony_ci refs_->DecWeakRefCount(this); 15373f4cbf05Sopenharmony_ci } 15383f4cbf05Sopenharmony_ci} 15393f4cbf05Sopenharmony_ci 15403f4cbf05Sopenharmony_ci} // namespace OHOS 15413f4cbf05Sopenharmony_ci 15423f4cbf05Sopenharmony_ci#endif 15433f4cbf05Sopenharmony_ci 15443f4cbf05Sopenharmony_ci/**@}*/ 1545