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