1485 lines
40 KiB
C++
1485 lines
40 KiB
C++
/*
|
|
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
/**
|
|
* @file refbase.h
|
|
*
|
|
* @brief Provide smart pointer implemented in c_utils.
|
|
*/
|
|
|
|
/**
|
|
* @defgroup SmartPointer
|
|
* @{
|
|
* @brief SmartPointer is a pointer-like class.
|
|
*
|
|
* This class simulates a pointer while providing
|
|
* enhanced features, such as automatic memory management.\n
|
|
* Automatic memory management helps to deallocate
|
|
* memory resources correctly when an object's life time expires.
|
|
*/
|
|
|
|
#ifndef UTILS_BASE_REFBASE_H
|
|
#define UTILS_BASE_REFBASE_H
|
|
|
|
#include <atomic>
|
|
#include <functional>
|
|
#ifdef DEBUG_REFBASE
|
|
#include <mutex>
|
|
#endif
|
|
|
|
namespace OHOS {
|
|
/**
|
|
* @ingroup SmartPointer
|
|
* @brief A value indicates no strong references ever.
|
|
*/
|
|
#define INITIAL_PRIMARY_VALUE (1 << 28)
|
|
|
|
class RefBase;
|
|
|
|
#if ((defined DEBUG_REFBASE) && (!defined PRINT_TRACK_AT_ONCE))
|
|
class RefTracker;
|
|
#endif
|
|
|
|
/**
|
|
* @ingroup SmartPointer
|
|
* @brief Reference counter class. Such a class records two kinds
|
|
* of references to the corresponding RefBase object and one kind
|
|
* of references to the RefCounter object itself.
|
|
*
|
|
* There are two different references for a single object.\n
|
|
* A strong reference holds the reference directly pointing to the object,
|
|
* and the object should be alive as long as the strong reference exists.\n
|
|
* A weak reference holds a reference indirectly pointing to the object,
|
|
* and the object is not always alive/existent
|
|
* even if the weak reference exists.
|
|
* @note The preceding descriptions are valid only when smart pointers
|
|
* are properly used.
|
|
*/
|
|
class RefCounter {
|
|
public:
|
|
/**
|
|
* @brief Callback function used to destroy the corresponding
|
|
* RefBase object.
|
|
*/
|
|
using RefPtrCallback = std::function<void()>;
|
|
friend class RefBase;
|
|
|
|
RefCounter();
|
|
|
|
explicit RefCounter(RefCounter *counter);
|
|
|
|
RefCounter &operator=(const RefCounter &counter);
|
|
|
|
virtual ~RefCounter();
|
|
|
|
/**
|
|
* @brief Sets the callback function.
|
|
*
|
|
* @param callback Callback function used to delete
|
|
* the corresponding RefBase object.
|
|
*/
|
|
void SetCallback(const RefPtrCallback& callback);
|
|
|
|
/**
|
|
* @brief Removes the current callback function by setting it to a `nullptr`.
|
|
*/
|
|
void RemoveCallback();
|
|
|
|
/**
|
|
* @brief Gets the count of references to the RefCounter object.
|
|
*
|
|
* @return Count of references to the RefCounter object.
|
|
*/
|
|
int GetRefCount();
|
|
|
|
/**
|
|
* @brief Increments the count of references to the RefCounter object by 1.
|
|
*/
|
|
void IncRefCount();
|
|
|
|
/**
|
|
* @brief Decrements the count of references to the RefCounter object by 1.
|
|
*
|
|
* Once the count reaches 0 after being decremented,
|
|
* `delete this` will be called to deallocate this RefCounter object.
|
|
*/
|
|
void DecRefCount();
|
|
|
|
/**
|
|
* @brief Checks if the pointer to the callback function is a `nullptr`.
|
|
*
|
|
* @return `true` if the callback function is a `nullptr`;
|
|
* `false` otherwise.
|
|
*/
|
|
bool IsRefPtrValid();
|
|
|
|
/**
|
|
* @brief Increments the count of strong references to the
|
|
* corresponding RefBase object by 1.
|
|
*
|
|
* @return Original count before increment.
|
|
*/
|
|
int IncStrongRefCount(const void *objectId);
|
|
|
|
/**
|
|
* @brief Decrements the count of strong references to the
|
|
* corresponding RefBase object by 1.
|
|
*
|
|
* @return Original count before decrement.
|
|
* @note If the strong reference never exists,
|
|
* decrement will be ineffective.
|
|
*/
|
|
int DecStrongRefCount(const void *objectId);
|
|
|
|
/**
|
|
* @brief Gets the count of strong references to the
|
|
* corresponding RefBase object.
|
|
*
|
|
* @return Count of strong references.
|
|
*/
|
|
int GetStrongRefCount();
|
|
|
|
/**
|
|
* @brief Increments the count weak references to the
|
|
* corresponding RefBase object by 1.
|
|
*
|
|
* @return Original count before increment.
|
|
*/
|
|
int IncWeakRefCount(const void *objectId);
|
|
|
|
/**
|
|
* @brief Decrements the count of weak references to the
|
|
* corresponding RefBase object by 1.
|
|
*
|
|
* @return Original (before decrement) value of atomicWeak_.
|
|
* @note If the count reaches 0 after being decremented, the
|
|
* corresponding RefBase object with no strong reference ever,
|
|
* or the RefBase object with 0 strong reference but an extended
|
|
* 'life time', will be deallocated.
|
|
*/
|
|
int DecWeakRefCount(const void *objectId);
|
|
|
|
/**
|
|
* @brief Gets the count of weak references to the
|
|
* corresponding RefBase object.
|
|
*
|
|
* @return Count of weak references.
|
|
*/
|
|
int GetWeakRefCount();
|
|
|
|
/**
|
|
* @brief Sets the number of attempts to increment.
|
|
*/
|
|
void SetAttemptAcquire();
|
|
|
|
/**
|
|
* @brief Check if the number of attempts is greater than 0.
|
|
*
|
|
* @return `true` if the number of attempts is greater than 0;
|
|
* `false` otherwise.
|
|
*/
|
|
bool IsAttemptAcquireSet();
|
|
|
|
/**
|
|
* @brief Clears number of attempts to increment.
|
|
*/
|
|
void ClearAttemptAcquire();
|
|
|
|
/**
|
|
* @brief Attempts to increment the count of strong references to the
|
|
* corresponding RefBase object by 1.
|
|
*
|
|
* @param outCount If the attempt success, the original value
|
|
* (before increment) of the count will be stored here.
|
|
* @return `true` if the attempt is successful; `false` otherwise.
|
|
*/
|
|
bool AttemptIncStrongRef(const void *objectId, int &outCount);
|
|
|
|
// Only for IPC use.
|
|
/**
|
|
* @brief Attempts to increment the count of strong references to the
|
|
* the corresponding RefBase object by 1 (simplified).
|
|
*
|
|
* @return `true` if the attempt is successful; `false` otherwise.
|
|
* @note Only for IPC use.
|
|
*/
|
|
bool AttemptIncStrong(const void *objectId);
|
|
|
|
/**
|
|
* @brief Checks if the corresponding RefBase object
|
|
* has an extended life-time.
|
|
*
|
|
* @return `true` if success; `false` otherwise.
|
|
*/
|
|
bool IsLifeTimeExtended();
|
|
|
|
/**
|
|
* @brief Extends the life-time of corresponding RefBase object.
|
|
*
|
|
* This allows the corresponding object keep alive
|
|
* even if there is no strong reference.
|
|
* @note The RefBase object will be deallocated
|
|
* if the count of weak references also reaches 0.
|
|
*/
|
|
void ExtendObjectLifetime();
|
|
|
|
#if ((defined DEBUG_REFBASE) && (!defined TRACK_ALL))
|
|
/**
|
|
* @brief Enables tracking. It is applicable to debugging only.
|
|
*/
|
|
void EnableTracker();
|
|
#endif
|
|
|
|
private:
|
|
std::atomic<int> atomicStrong_; // = (num of sptr) or Initial-value
|
|
std::atomic<int> atomicWeak_; // = (num of sptr)+(num of WeakRefCounter)
|
|
std::atomic<int> atomicRefCount_; // = (num of WeakRefCounter) + 1
|
|
std::atomic<unsigned int> atomicFlags_; // Life-time extended flag
|
|
std::atomic<int> atomicAttempt_; // Number of attempts
|
|
RefPtrCallback callback_ = nullptr; // Callback function to deallocate the corresponding RefBase object
|
|
static constexpr unsigned int FLAG_EXTEND_LIFE_TIME = 0x00000002; // Extended life-time bit to be set via logic-OR
|
|
#ifdef DEBUG_REFBASE
|
|
#ifdef TRACK_ALL
|
|
bool enableTrack = true;
|
|
#else
|
|
bool enableTrack = false;
|
|
#endif
|
|
std::mutex trackerMutex; // To ensure refTracker be thread-safe
|
|
#ifdef PRINT_TRACK_AT_ONCE
|
|
void PrintRefs(const void* objectId);
|
|
#else
|
|
RefTracker* refTracker = nullptr;
|
|
void GetNewTrace(const void* objectId);
|
|
void PrintTracker();
|
|
#endif
|
|
#endif
|
|
};
|
|
|
|
/**
|
|
* @ingroup SmartPointer
|
|
* @brief An intermediate class to represent the weak reference
|
|
* to the correspond RefBase object.
|
|
*
|
|
* A WeakRefCounter object can be shared by multiple wptr objects.\n
|
|
* It holds the references to the corresponding RefBase and RefCounter object.
|
|
* Those two references will be set as `nullptr` when the weak referenced
|
|
* target and its RefCounter object are deallocated. The WeakRefCounter
|
|
* object can remain alive even if the referenced target is deallocated.
|
|
*/
|
|
class WeakRefCounter {
|
|
public:
|
|
/**
|
|
* @brief Constructs a WeakRefCounter object.
|
|
*
|
|
* @param counter Pointer to corresponding RefCounter object.
|
|
* @param cookie Pointer to corresponding RefBase object.
|
|
*/
|
|
WeakRefCounter(RefCounter *counter, void *cookie);
|
|
|
|
virtual ~WeakRefCounter();
|
|
|
|
/**
|
|
* @brief Gets the current pointer to the corresponding RefBase object.
|
|
*
|
|
* @return A void pointer to the RefBase object.
|
|
* If the corresponding object is not alive, a `nullptr` will be returned.
|
|
* @note A void pointer means that you should cast it to the real type,
|
|
* since it can be any subclass of RefBase.
|
|
*/
|
|
void *GetRefPtr();
|
|
|
|
/**
|
|
* @brief Increments the count of references to this WeakRefCounter object.
|
|
*
|
|
* @note This count is different from the count of weak references
|
|
* in RefCounter. It is equal to the count of wptrs directly
|
|
* referenced to this WeakRefCount object.
|
|
* @see RefCounter
|
|
*/
|
|
void IncWeakRefCount(const void *objectId);
|
|
|
|
/**
|
|
* @brief Decrements the count of references to this WeakRefCounter object.
|
|
*
|
|
* @note This WeakRefCounter object will be deallocated when this count
|
|
* reaches 0.
|
|
*/
|
|
void DecWeakRefCount(const void *objectId);
|
|
|
|
/**
|
|
* @brief Gets the count recorded by this WeakRefCounter object.
|
|
*
|
|
* @return Count recorded by this WeakRefCounter object.
|
|
* @note The count is different from that in RefCounter.
|
|
* @see RefCounter::GetWeakRefCount()
|
|
*/
|
|
int GetWeakRefCount() const;
|
|
|
|
/**
|
|
* @brief Attempts to increment the count of strong references to
|
|
* the corresponding RefBase object (to promote a wptr to a sptr).
|
|
*
|
|
* @return `true` after a success increment.
|
|
*/
|
|
bool AttemptIncStrongRef(const void *objectId);
|
|
|
|
private:
|
|
std::atomic<int> atomicWeak_; // Count of references to this
|
|
// WeakRefCounter object
|
|
// The value is equal to the count of wptrs
|
|
// that references this WeakRefCounter object.
|
|
RefCounter *refCounter_ = nullptr; // Reference to the RefCounter object of
|
|
// the corresponding RefBase object
|
|
void *cookie_ = nullptr; // Pointer to the corresponding RefBase object
|
|
};
|
|
|
|
/**
|
|
* @ingroup SmartPointer
|
|
* @brief A base class of subclasses that can be managed by SmartPointer.
|
|
*
|
|
* @note All classes which intend to be managed by SmartPointer should be
|
|
* derived from RefBase.
|
|
*/
|
|
class RefBase {
|
|
public:
|
|
RefBase();
|
|
|
|
/**
|
|
* @brief Copy constructor of RefBase.
|
|
*
|
|
* @note This function constructs a new RefCounter object
|
|
* and binds it to the RefBase object.
|
|
*/
|
|
RefBase(const RefBase &);
|
|
|
|
/**
|
|
* @brief Copy assignment operator of RefBase.
|
|
*
|
|
* @note This function unbinds this RefBase object from the
|
|
* original RefCounter object, and then binds it to the
|
|
* newly constructed RefCounter object.
|
|
*/
|
|
RefBase &operator=(const RefBase &);
|
|
|
|
/**
|
|
* @brief Move constructor of RefBase.
|
|
*/
|
|
RefBase(RefBase &&other) noexcept;
|
|
|
|
/**
|
|
* @brief Move assignment operator of RefBase.
|
|
*
|
|
* @note This function binds this RefBase object with the RefCounter
|
|
* object of the argument `other`, which will unbind the
|
|
* RefCounter object. No counts operation will be processed.
|
|
*/
|
|
RefBase &operator=(RefBase &&other) noexcept;
|
|
|
|
virtual ~RefBase();
|
|
|
|
/**
|
|
* @brief Callback function to deallocate this object.
|
|
*
|
|
* This function provides the default implementation to deallocate
|
|
* this RefBase object by simply calling `delete(this)`.
|
|
*/
|
|
virtual void RefPtrCallback();
|
|
|
|
/**
|
|
* @brief Extends the life time of the RefBase object.
|
|
*
|
|
* @note The object whose life time has been extended will not be
|
|
* deallocated if the count of weak references, instead of strong
|
|
* references, reaches 0.
|
|
*/
|
|
void ExtendObjectLifetime();
|
|
|
|
/**
|
|
* @brief Increments the count of strong references.
|
|
*
|
|
* `OnFirstStrongRef()`, which is an empty function by default,
|
|
* will be called when the first strong reference is established.
|
|
*
|
|
* @note This function automatically increments the count of weak
|
|
* references meanwhile.
|
|
*/
|
|
void IncStrongRef(const void *objectId);
|
|
|
|
/**
|
|
* @brief Decrements the count of strong references.
|
|
*
|
|
* If the life time is not extended, this object will be deallocated
|
|
* when the count of strong references reaches 0.\n
|
|
* `OnLastStrongRef()`, which is an empty function by default,
|
|
* will be called when the last strong reference is deleted.
|
|
*/
|
|
void DecStrongRef(const void *objectId);
|
|
|
|
/**
|
|
* @brief Gets the count of strong references.
|
|
*
|
|
* @return Count of strong references. The value is 0 if the
|
|
* corresponding RefCounter object does not exist.
|
|
* @note This function is valid only when corresponding RefCounter
|
|
* object exists.
|
|
*/
|
|
int GetSptrRefCount();
|
|
|
|
/**
|
|
* @brief Creates a weak reference to this RefBase object.
|
|
*
|
|
* @param cookie Void pointer to this RefBase object.
|
|
* @return Pointer to the newly created WeakRefCounter object.
|
|
* @note Use this function with related functions of wptr.
|
|
* Do not use it independently.
|
|
*/
|
|
WeakRefCounter *CreateWeakRef(void *cookie);
|
|
|
|
/**
|
|
* @brief Gets the pointer to corresponding counter object.
|
|
*
|
|
* @return Pointer to the counter object.
|
|
*/
|
|
RefCounter *GetRefCounter() const;
|
|
|
|
/**
|
|
* @brief Increments the count of weak references.
|
|
*
|
|
* @note This function is valid only when corresponding RefCounter
|
|
* object exists.
|
|
*/
|
|
void IncWeakRef(const void *objectId);
|
|
|
|
/**
|
|
* @brief Decrements the count of weak references.
|
|
*
|
|
* @note This function is valid only when corresponding RefCounter
|
|
* object exists.
|
|
*/
|
|
void DecWeakRef(const void *objectId);
|
|
|
|
/**
|
|
* @brief Gets the count of weak references.
|
|
*
|
|
* @return Count of weak references. The value is 0 if the corresponding
|
|
* RefCounter object does not exist.
|
|
*/
|
|
int GetWptrRefCount();
|
|
|
|
/**
|
|
* @brief Attempts to increment the count of strong references.
|
|
*
|
|
* `OnFirstStrongRef()`, which is an empty function by default, will be
|
|
* called when the first strong reference is established.
|
|
*
|
|
* @return `true` if the increment is successful; `false` otherwise.
|
|
* @note The count of attempts will increment by 1
|
|
* after a successful increment.
|
|
*/
|
|
bool AttemptAcquire(const void *objectId);
|
|
|
|
/**
|
|
* @brief Attempts to increment the count of strong references.
|
|
*
|
|
* `OnFirstStrongRef()`, which is an empty function by default, will be
|
|
* called when the first strong reference is established.
|
|
* @return `true` if the increment is successful; `false` otherwise.
|
|
* @note Use this function in the copy constructor of sptr in scenario of
|
|
* interaction between sptr and wptr. Avoid using it independently.
|
|
*/
|
|
bool AttemptIncStrongRef(const void *objectId);
|
|
|
|
// Only for IPC use.
|
|
/**
|
|
* @brief Attempts to increment the count of strong references.
|
|
*
|
|
* @return `true` if the increment is successful; `false` otherwise.
|
|
* @note If the operation is successful, the count of successful attempts
|
|
* will increment by 1.
|
|
* @note This function is a simplified version of `AttemptAcquire`.
|
|
* It is only for IPC use.
|
|
*/
|
|
bool AttemptIncStrong(const void *objectId);
|
|
|
|
/**
|
|
* @brief Checks if the count of successful attempts is greater than 0.
|
|
*
|
|
* @return `true` if the count of successful attempts is greater than 0;
|
|
* `false` if the count of successful attempts is not greater than 0
|
|
* or the corresponding RefCounter object does not exist.
|
|
*/
|
|
bool IsAttemptAcquireSet();
|
|
|
|
/**
|
|
* @brief Checks if the life time of this RefBase object has been extended.
|
|
*
|
|
* @return `true` if the life time of this RefBase object has been extended;
|
|
* `false` if the RefBase object has a normal life time or the corresponding
|
|
* RefCounter object does not exist.
|
|
*/
|
|
bool IsExtendLifeTimeSet();
|
|
|
|
/**
|
|
* @brief Called when the first strong reference is established.
|
|
*
|
|
* @note It is an empty function by default.
|
|
*/
|
|
virtual void OnFirstStrongRef(const void *);
|
|
|
|
/**
|
|
* @brief Called when the last strong reference is deleted.
|
|
*
|
|
* @note It is an empty function by default.
|
|
*/
|
|
virtual void OnLastStrongRef(const void *);
|
|
|
|
/**
|
|
* @brief Called when the last weak reference is deleted.
|
|
*
|
|
* @note It is an empty function by default.
|
|
*/
|
|
virtual void OnLastWeakRef(const void *);
|
|
|
|
/**
|
|
* @brief Called when `wptr::Promote()` is invoked.
|
|
*
|
|
* @return `true` if success; `false` otherwise.
|
|
*/
|
|
virtual bool OnAttemptPromoted(const void *);
|
|
|
|
/**
|
|
* @brief Enables tracking of the RefBase object. This function will
|
|
* be implemented only if DEBUG_REFBASE, but not TRACK_ALL, is defined.
|
|
*/
|
|
void EnableTracker();
|
|
|
|
private:
|
|
RefCounter *refs_ = nullptr; // Pointer to the corresponding reference
|
|
// counter of this RefBase object
|
|
};
|
|
|
|
template <typename T>
|
|
class wptr;
|
|
|
|
/**
|
|
* @ingroup SmartPointer
|
|
* @brief Strong reference smart pointer to a RefBase object
|
|
* (or an object of its subclass).
|
|
*
|
|
* It directly reference the RefBase object.
|
|
*
|
|
* @tparam T Specific class type managed by sptr.
|
|
* This class must inherit from RefBase.
|
|
*/
|
|
template <typename T>
|
|
class sptr {
|
|
friend class wptr<T>;
|
|
|
|
public:
|
|
sptr();
|
|
|
|
~sptr();
|
|
|
|
/**
|
|
* @brief Constructor with the specified object to be managed.
|
|
*
|
|
* @note A null sptr will be created if `other` is `nullptr`.
|
|
* @param other Object to be managed by wptr.
|
|
*/
|
|
sptr(T *other);
|
|
|
|
/**
|
|
* @brief Copy constructor for sptr with the managed class type (T).
|
|
*
|
|
* @param other Input sptr object.
|
|
*/
|
|
sptr(const sptr<T> &other);
|
|
|
|
/**
|
|
* @brief Move constructor.
|
|
*
|
|
* @note `other` will be set to a null sptr.
|
|
* @param other Input sptr object.
|
|
*/
|
|
sptr(sptr<T> &&other);
|
|
|
|
/**
|
|
* @brief Move assignment operator.
|
|
*
|
|
* @param other Input sptr object.
|
|
* @note The original strong reference in target sptr object will
|
|
* be removed.
|
|
*/
|
|
sptr<T> &operator=(sptr<T> &&other);
|
|
|
|
/**
|
|
* @brief Copy Constructor for sptr with the managed class type (O).
|
|
*
|
|
* @tparam O Another specific class type managed by `other`.
|
|
* @param other Input sptr object.
|
|
*/
|
|
template <typename O>
|
|
sptr(const sptr<O> &other);
|
|
|
|
/**
|
|
* @brief Constructor used to promote the process of wptr.
|
|
*
|
|
* @param p WeakRefCounter object which hold the reference to the
|
|
* managed object.
|
|
* @param force Used to distinguish from other constructors.
|
|
*/
|
|
inline sptr(WeakRefCounter *p, bool force);
|
|
|
|
/**
|
|
* @brief Gets the pointer to the managed object.
|
|
*
|
|
* @return Pointer of the specific managed class type.
|
|
*/
|
|
inline T *GetRefPtr() const
|
|
{
|
|
return refs_;
|
|
}
|
|
|
|
/**
|
|
* @brief Sets the pointer to the managed object.
|
|
*
|
|
* @param other Another pointer object to be managed by sptr.
|
|
* @note Avoid using this function independently. Otherwise,
|
|
* a mismatch of the reference count will arise, leading to memory problems.
|
|
*/
|
|
inline void ForceSetRefPtr(T *other);
|
|
|
|
/**
|
|
* @brief Removes the reference to the managed object held by current sptr.
|
|
*
|
|
* @note This function will make this sptr a "null sptr".
|
|
*/
|
|
void clear();
|
|
|
|
/**
|
|
* @brief Type conversion operator.
|
|
*
|
|
* @return Raw pointer to the managed object.
|
|
* @note The sptr object will not be converted. Only the member raw
|
|
* pointer will be returned.
|
|
*/
|
|
inline operator T *() const
|
|
{
|
|
return refs_;
|
|
}
|
|
|
|
/**
|
|
* @brief Dereference operator.
|
|
*
|
|
* This function will return the object managed by this sptr.
|
|
*
|
|
* @return Reference to the specific object managed by sptr.
|
|
*/
|
|
inline T &operator*() const
|
|
{
|
|
return *refs_;
|
|
}
|
|
|
|
/**
|
|
* @brief Member selection operator.
|
|
*
|
|
* This function will return the specified member of the object
|
|
* managed by this sptr.
|
|
*/
|
|
inline T *operator->() const
|
|
{
|
|
return refs_;
|
|
}
|
|
|
|
/**
|
|
* @brief Logical-NOT operator, which is used to check if
|
|
* the sptr is a "null sptr".
|
|
*
|
|
* @return `true` if sptr is a "null sptr"; `false` otherwise.
|
|
*/
|
|
inline bool operator!() const
|
|
{
|
|
return refs_ == nullptr;
|
|
}
|
|
|
|
/**
|
|
* @brief Copy assignment operator with the specified object to be managed.
|
|
*
|
|
* @note The original reference will be removed, and a new reference to the
|
|
* input object will be established.
|
|
* @param other Another object to be managed by this sptr.
|
|
*/
|
|
sptr<T> &operator=(T *other);
|
|
|
|
/**
|
|
* @brief Copy assignment operator for sptr with
|
|
* the same managed class type (T).
|
|
*
|
|
* @note The original reference will be removed, and the same object
|
|
* with the input sptr object will be managed by this sptr.
|
|
* @param other Another sptr object with the same managed class type (T).
|
|
*/
|
|
sptr<T> &operator=(const sptr<T> &other);
|
|
|
|
/**
|
|
* @brief Copy assignment operator for wptr with
|
|
* the same managed class type (T).
|
|
*
|
|
* @note The original reference will be removed, and the same object
|
|
* with the input wptr object will be managed by this sptr.
|
|
* @note If the operation fails, this sptr will turn to be a "null sptr".
|
|
* @param other Another wptr object with the same managed class type (T).
|
|
*/
|
|
sptr<T> &operator=(const wptr<T> &other);
|
|
|
|
/**
|
|
* @brief Copy assignment operator for sptr with
|
|
* a different managed class type (O).
|
|
*
|
|
* @note The original reference will be removed, and the same object
|
|
* with the input sptr object will be managed by this sptr.
|
|
* @note This sptr will interpret the managed object as the type (T).
|
|
* @param other Another sptr object with a different managed class type (O).
|
|
*/
|
|
template <typename O>
|
|
sptr<T> &operator=(const sptr<O> &other);
|
|
|
|
/**
|
|
* @brief Equal-to operator between the sptr and raw pointer.
|
|
*
|
|
* @param other Input raw pointer.
|
|
* @return `true` if the sptr points to the same object with input
|
|
* raw pointer; `false` otherwise.
|
|
*/
|
|
bool operator==(const T *other) const;
|
|
|
|
/**
|
|
* @brief Not-equal-to operator between the sptr and raw pointer.
|
|
*
|
|
* @param other Input raw pointer.
|
|
* @return `true` if the sptr does not point to the same object
|
|
* with input raw pointer; `false` otherwise.
|
|
*/
|
|
inline bool operator!=(const T *other) const
|
|
{
|
|
return !operator==(other);
|
|
}
|
|
|
|
/**
|
|
* @brief Equal-to operator between the sptr and wptr.
|
|
*
|
|
* @param other Input wptr.
|
|
* @return `true` if the same object is managed by the sptr and wptr;
|
|
* `false` otherwise.
|
|
*/
|
|
bool operator==(const wptr<T> &other) const;
|
|
|
|
/**
|
|
* @brief Not-equal-to operator between the sptr and wptr.
|
|
*
|
|
* @param other Input wptr.
|
|
* @return `true` if different objects are managed by the sptr and wptr;
|
|
* `false` otherwise.
|
|
*/
|
|
inline bool operator!=(const wptr<T> &other) const
|
|
{
|
|
return !operator==(other);
|
|
}
|
|
|
|
/**
|
|
* @brief Equal-to operator between two sptrs.
|
|
*
|
|
* @param other Input sptr.
|
|
* @return `true` if the same object is managed by two sptrs;
|
|
* `false` otherwise.
|
|
*/
|
|
bool operator==(const sptr<T> &other) const;
|
|
|
|
/**
|
|
* @brief Not-equal-to operator between sptrs.
|
|
*
|
|
* @param other Input sptr.
|
|
* @return `true` if different objects are managed by two sptrs;
|
|
* `false` otherwise.
|
|
*/
|
|
inline bool operator!=(const sptr<T> &other) const
|
|
{
|
|
return !operator==(other);
|
|
}
|
|
|
|
private:
|
|
T *refs_ = nullptr; // Raw pointer to the specific managed object
|
|
};
|
|
|
|
template <typename T>
|
|
inline void sptr<T>::ForceSetRefPtr(T *other)
|
|
{
|
|
refs_ = other;
|
|
}
|
|
|
|
template <typename T>
|
|
inline sptr<T>::sptr()
|
|
{
|
|
refs_ = nullptr;
|
|
}
|
|
|
|
template <typename T>
|
|
inline sptr<T>::sptr(T *other)
|
|
{
|
|
refs_ = other;
|
|
if (refs_ != nullptr) {
|
|
refs_->IncStrongRef(this);
|
|
}
|
|
}
|
|
|
|
template <typename T>
|
|
inline sptr<T>::sptr(const sptr<T> &other)
|
|
{
|
|
refs_ = other.GetRefPtr();
|
|
if (refs_ != nullptr) {
|
|
refs_->IncStrongRef(this);
|
|
}
|
|
}
|
|
|
|
template <typename T>
|
|
sptr<T>::sptr(sptr<T> &&other)
|
|
{
|
|
refs_ = other.GetRefPtr();
|
|
other.ForceSetRefPtr(nullptr);
|
|
}
|
|
|
|
template <typename T>
|
|
sptr<T> &sptr<T>::operator=(sptr<T> &&other)
|
|
{
|
|
if (refs_ != nullptr) {
|
|
refs_->DecStrongRef(this);
|
|
}
|
|
refs_ = other.GetRefPtr();
|
|
other.ForceSetRefPtr(nullptr);
|
|
return *this;
|
|
}
|
|
|
|
template <typename T>
|
|
template <typename O>
|
|
sptr<T>::sptr(const sptr<O> &other) : refs_(other.GetRefPtr())
|
|
{
|
|
if (refs_ != nullptr) {
|
|
refs_->IncStrongRef(this);
|
|
}
|
|
}
|
|
|
|
template <typename T>
|
|
inline sptr<T> &sptr<T>::operator=(T *other)
|
|
{
|
|
if (other != nullptr) {
|
|
other->IncStrongRef(this);
|
|
}
|
|
|
|
if (refs_ != nullptr) {
|
|
refs_->DecStrongRef(this);
|
|
}
|
|
|
|
refs_ = other;
|
|
return *this;
|
|
}
|
|
|
|
template <typename T>
|
|
inline sptr<T> &sptr<T>::operator=(const sptr<T> &other)
|
|
{
|
|
T *otherRef(other.GetRefPtr());
|
|
if (otherRef != nullptr) {
|
|
otherRef->IncStrongRef(this);
|
|
}
|
|
|
|
if (refs_ != nullptr) {
|
|
refs_->DecStrongRef(this);
|
|
}
|
|
|
|
refs_ = otherRef;
|
|
return *this;
|
|
}
|
|
|
|
template <typename T>
|
|
inline sptr<T> &sptr<T>::operator=(const wptr<T> &other)
|
|
{
|
|
if (refs_ != nullptr) {
|
|
refs_->DecStrongRef(this);
|
|
}
|
|
if ((other != nullptr) && other.AttemptIncStrongRef(this)) {
|
|
refs_ = other.GetRefPtr();
|
|
} else {
|
|
refs_ = nullptr;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
template <typename T>
|
|
template <typename O>
|
|
sptr<T> &sptr<T>::operator=(const sptr<O> &other)
|
|
{
|
|
T *otherRef(other.GetRefPtr());
|
|
if (otherRef != nullptr) {
|
|
otherRef->IncStrongRef(this);
|
|
}
|
|
|
|
if (refs_ != nullptr) {
|
|
refs_->DecStrongRef(this);
|
|
}
|
|
|
|
refs_ = otherRef;
|
|
return *this;
|
|
}
|
|
|
|
template <typename T>
|
|
inline bool sptr<T>::operator==(const T *other) const
|
|
{
|
|
return other == refs_;
|
|
}
|
|
|
|
template <typename T>
|
|
inline bool sptr<T>::operator==(const wptr<T> &other) const
|
|
{
|
|
return refs_ == other.GetRefPtr();
|
|
}
|
|
|
|
template <typename T>
|
|
inline bool sptr<T>::operator==(const sptr<T> &other) const
|
|
{
|
|
return refs_ == other.GetRefPtr();
|
|
}
|
|
|
|
template<typename T>
|
|
void sptr<T>::clear()
|
|
{
|
|
if (refs_) {
|
|
refs_->DecStrongRef(this);
|
|
refs_ = 0;
|
|
}
|
|
}
|
|
|
|
template <typename T>
|
|
inline sptr<T>::~sptr()
|
|
{
|
|
if (refs_ != nullptr) {
|
|
refs_->DecStrongRef(this);
|
|
}
|
|
}
|
|
|
|
template <typename T>
|
|
inline sptr<T>::sptr(WeakRefCounter *p, bool /* force */)
|
|
{
|
|
if ((p != nullptr) && p->AttemptIncStrongRef(this)) {
|
|
refs_ = reinterpret_cast<T *>(p->GetRefPtr());
|
|
} else {
|
|
refs_ = nullptr;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @ingroup SmartPointer
|
|
* @brief Weak reference smart pointer to a RefBase object
|
|
* (or an object of its subclass).
|
|
*
|
|
* A weak reference indirectly references the RefBase object
|
|
* and directly references the WeakRefCounter object.
|
|
*
|
|
* @tparam T Specific class type managed by wptr.
|
|
* This class must inherit from RefBase.
|
|
*/
|
|
template <typename T>
|
|
class wptr {
|
|
template <typename O>
|
|
friend class wptr;
|
|
|
|
public:
|
|
wptr();
|
|
|
|
/**
|
|
* @brief Constructor with the specified object to be managed.
|
|
*
|
|
* This function will create WeakRefCounter object for `other`
|
|
* and set the count of weak references to 1.
|
|
*
|
|
* @note A WeakRefCounter object will not be created if `other`
|
|
* is a `nullptr`.
|
|
*
|
|
* @param other Object to be managed by wptr.
|
|
*/
|
|
wptr(T *other);
|
|
|
|
/**
|
|
* @brief Copy constructor for wptr with the same managed class type (T).
|
|
*
|
|
* This function will share the WeakRefCounter object of `other` with this
|
|
* wptr and set the count of weak references properly.
|
|
*
|
|
* @param other Another wptr with the same managed class type (T).
|
|
*/
|
|
wptr(const wptr<T> &other);
|
|
|
|
/**
|
|
* @brief Copy constructor for sptr with the same managed class type (T).
|
|
*
|
|
* This function will create a WeakRefCounter object for the managed
|
|
* object of `other`, and set the count of weak references properly.
|
|
*
|
|
* @param other Another sptr with the same managed class type (T).
|
|
* @tparam T Specific class type managed by `other`.
|
|
*/
|
|
wptr(const sptr<T> &other);
|
|
|
|
/**
|
|
* @brief Copy constructor for wptr with a different managed class type (O).
|
|
*
|
|
* This function is the same as wptr<T>::wptr(const wptr<T> &other).
|
|
*
|
|
* @tparam O Class type managed by `other`.
|
|
* @param other Another wptr with a different managed class type (O).
|
|
* @tparam T Specific class type managed by `other`.
|
|
*/
|
|
template <typename O>
|
|
wptr(const wptr<O> &other);
|
|
|
|
/**
|
|
* @brief Copy constructor for sptr with a different managed class type (O).
|
|
*
|
|
* This function is the same as wptr<T>::wptr(const sptr<T> &other).
|
|
*
|
|
* @param other Another sptr with the same managed class type (O).
|
|
* @tparam T Specific class type managed by `other`.
|
|
*/
|
|
template <typename O>
|
|
wptr(const sptr<O> &other);
|
|
|
|
/**
|
|
* @brief Copy assignment operator with the specified object to be managed.
|
|
*
|
|
* @note The current wptr will unbind the original WeakRefCounter object,
|
|
* create a new WeakRefCounter object, and then set the count of weak
|
|
* references properly.
|
|
* @param other Another object to be managed by this wptr.
|
|
*/
|
|
wptr<T> &operator=(T *other);
|
|
|
|
/**
|
|
* @brief Copy assignment operator with the specified object to be managed.
|
|
*
|
|
* @note Same with wptr<T> &operator=(T *other), but a pointer type casting
|
|
* which will not affect the type of `*other` is processed.
|
|
* @tparam O Specific class type managed by `other`.
|
|
* @param other Another object to be managed by this wptr.
|
|
*
|
|
*/
|
|
template <typename O>
|
|
wptr<T> &operator=(O *other);
|
|
|
|
/**
|
|
* @brief Copy assignment operator for wptr with the same managed class
|
|
* type (T).
|
|
*
|
|
* @note The current wptr will unbind the original WeakRefCounter object,
|
|
* share the WeakRefCounter object with `other`, and then set the count of
|
|
* weak references properly.
|
|
* @param other Another wptr object. Objects managed by it will also be
|
|
* managed by this wptr.
|
|
*/
|
|
wptr<T> &operator=(const wptr<T> &other);
|
|
|
|
/**
|
|
* @brief Copy assignment operator for sptr with the same managed class
|
|
* type (T).
|
|
*
|
|
* @note The current wptr will unbind the original WeakRefCounter object,
|
|
* create a new WeakRefCounter object, and then set the count of weak
|
|
* references properly.
|
|
* @param other A sptr object. Objects managed by it will also be
|
|
* managed by this wptr.
|
|
*/
|
|
wptr<T> &operator=(const sptr<T> &other);
|
|
|
|
/**
|
|
* @brief Copy assignment operator for wptr with a different managed class
|
|
* type (O).
|
|
*
|
|
* @note This function is the same as wptr<T> &operator=(const wptr<T> &).
|
|
* Note that no cast here is processed.
|
|
* @param other An wptr object. Objects managed by it will also be
|
|
* managed by this wptr.
|
|
* @tparam O Specific class type managed by `other`.
|
|
*/
|
|
template <typename O>
|
|
wptr<T> &operator=(const wptr<O> &other);
|
|
|
|
/**
|
|
* @brief Copy assignment operator for sptr with a different managed class
|
|
* type (O).
|
|
*
|
|
* @note This function is the same as
|
|
* wptr<T> &wptr<T>::operator=(const sptr<T> &).
|
|
* Note that no cast here is processed.
|
|
* @param other An sptr object. Objects managed by it will also be
|
|
* managed by this wptr.
|
|
* @tparam O Specific class type managed by `other`.
|
|
*/
|
|
template <typename O>
|
|
wptr<T> &operator=(const sptr<O> &other);
|
|
|
|
/**
|
|
* @brief Dereference operator.
|
|
*
|
|
* This function will return the object managed by this wptr.
|
|
*
|
|
* @return Specific object managed by wptr.
|
|
*/
|
|
inline T &operator*() const
|
|
{
|
|
return *GetRefPtr();
|
|
}
|
|
|
|
/**
|
|
* @brief Member selection operator.
|
|
*
|
|
* This function will return the specified object member managed
|
|
* by this wptr.
|
|
*/
|
|
inline T *operator->() const
|
|
{
|
|
return reinterpret_cast<T *>(refs_->GetRefPtr());
|
|
}
|
|
|
|
/**
|
|
* @brief Equal-to operator between the wptr and raw pointer.
|
|
*
|
|
* @param other Input raw pointer.
|
|
* @return `true` if two pointers have the same value; `false` otherwise.
|
|
*/
|
|
bool operator==(const T *other) const;
|
|
|
|
/**
|
|
* @brief Not-equal-to operator between the wptr and raw pointer.
|
|
*
|
|
* @param other Input raw pointer.
|
|
* @return `true` if two pointers have different values; `false` otherwise.
|
|
*/
|
|
inline bool operator!=(const T *other) const
|
|
{
|
|
return !operator==(other);
|
|
};
|
|
|
|
/**
|
|
* @brief Equal-to operator between two wptrs.
|
|
*
|
|
* @param other Input reference to a wptr object.
|
|
* @return `true` if two pointers have the same value; `false` otherwise.
|
|
*/
|
|
bool operator==(const wptr<T> &other) const;
|
|
|
|
/**
|
|
* @brief Not-equal-to operator between two wptrs.
|
|
*
|
|
* @param other Input reference to a wptr object.
|
|
* @return `true` if two pointers have different values; `false` otherwise.
|
|
*/
|
|
inline bool operator!=(const wptr<T> &other) const
|
|
{
|
|
return !operator==(other);
|
|
}
|
|
|
|
/**
|
|
* @brief Equal-to operator between the wptr and input sptr object.
|
|
*
|
|
* @param other Input reference to an sptr object.
|
|
* @return true` if two pointers have the same value; `false` otherwise.
|
|
*/
|
|
bool operator==(const sptr<T> &other) const;
|
|
|
|
/**
|
|
* @brief Not-equal-to operator between the wptr and input sptr object.
|
|
*
|
|
* @param other Input reference to an sptr object.
|
|
* @return `true` if two pointers have different values; `false` otherwise.
|
|
*/
|
|
inline bool operator!=(const sptr<T> &other) const
|
|
{
|
|
return !operator==(other);
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the pointer to the RefBase object.
|
|
*
|
|
* @return Raw pointer to the RefBase object.
|
|
* @note `nullptr` will be returned if the managed object has been
|
|
* deallocated.
|
|
*/
|
|
T *GetRefPtr() const;
|
|
|
|
/**
|
|
* @brief Gets the count of weak references in a WeakRefCounter object.
|
|
*
|
|
* The value indicates how many wptrs share the same WeakRefCounter object.
|
|
*
|
|
* @return Count of weak references.
|
|
* @note Only for test.
|
|
*/
|
|
inline int GetWeakRefCount() const
|
|
{
|
|
return refs_->GetWeakRefCount();
|
|
}
|
|
|
|
/**
|
|
* @brief Attempts to increment the count of strong references in
|
|
* the managed object.
|
|
*
|
|
* @return `true` if the increment is successful; `false` otherwise.
|
|
* @note Avoid using this function independently. Use `promote()` instead.
|
|
*/
|
|
inline bool AttemptIncStrongRef(const void *objectId) const
|
|
{
|
|
return refs_->AttemptIncStrongRef(objectId);
|
|
}
|
|
|
|
/**
|
|
* @brief Promotes a wptr to an sptr.
|
|
*
|
|
* This function will create an sptr object based on the object
|
|
* managed by this wptr.
|
|
*
|
|
* @note The original weak reference will be retained.
|
|
* If the promotion fails, a "null sptr" will be returned.
|
|
*/
|
|
const sptr<T> promote() const;
|
|
|
|
~wptr();
|
|
|
|
private:
|
|
WeakRefCounter *refs_ = nullptr; // Pointer to the corresponding WeakRefCounter object
|
|
};
|
|
|
|
template <typename T>
|
|
inline T *wptr<T>::GetRefPtr() const
|
|
{
|
|
return (refs_ != nullptr) ? reinterpret_cast<T *>(refs_->GetRefPtr()) : nullptr;
|
|
}
|
|
|
|
template <typename T>
|
|
wptr<T>::wptr()
|
|
{
|
|
refs_ = nullptr;
|
|
}
|
|
|
|
template <typename T>
|
|
wptr<T>::wptr(T *other)
|
|
{
|
|
if (other != nullptr) {
|
|
refs_ = other->CreateWeakRef(other);
|
|
if (refs_ != nullptr) {
|
|
refs_->IncWeakRefCount(this);
|
|
}
|
|
} else {
|
|
refs_ = nullptr;
|
|
}
|
|
}
|
|
|
|
template <typename T>
|
|
wptr<T>::wptr(const wptr<T> &other)
|
|
{
|
|
refs_ = other.refs_;
|
|
if (refs_ != nullptr) {
|
|
refs_->IncWeakRefCount(this);
|
|
}
|
|
}
|
|
|
|
template <typename T>
|
|
wptr<T>::wptr(const sptr<T> &other)
|
|
{
|
|
if (other.GetRefPtr() != nullptr) {
|
|
refs_ = other->CreateWeakRef(other.GetRefPtr());
|
|
if (refs_ != nullptr) {
|
|
refs_->IncWeakRefCount(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
template <typename T>
|
|
template <typename O>
|
|
wptr<T>::wptr(const wptr<O> &other)
|
|
{
|
|
refs_ = other.refs_;
|
|
if (refs_ != nullptr) {
|
|
refs_->IncWeakRefCount(this);
|
|
}
|
|
}
|
|
|
|
template <typename T>
|
|
template <typename O>
|
|
wptr<T>::wptr(const sptr<O> &other)
|
|
{
|
|
if (other.GetRefPtr() != nullptr) {
|
|
refs_ = other->CreateWeakRef(other.GetRefPtr());
|
|
if (refs_ != nullptr) {
|
|
refs_->IncWeakRefCount(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
template <typename T>
|
|
wptr<T> &wptr<T>::operator=(T *other)
|
|
{
|
|
WeakRefCounter *newWeakRef = nullptr;
|
|
if (other != nullptr) {
|
|
newWeakRef = other->CreateWeakRef(other);
|
|
if (newWeakRef != nullptr) {
|
|
newWeakRef->IncWeakRefCount(this);
|
|
}
|
|
}
|
|
|
|
if (refs_ != nullptr) {
|
|
refs_->DecWeakRefCount(this);
|
|
}
|
|
|
|
refs_ = newWeakRef;
|
|
return *this;
|
|
}
|
|
|
|
template <typename T>
|
|
template <typename O>
|
|
wptr<T> &wptr<T>::operator=(O *other)
|
|
{
|
|
T *object = reinterpret_cast<T *>(other);
|
|
WeakRefCounter *newWeakRef = nullptr;
|
|
if (object != nullptr) {
|
|
newWeakRef = object->CreateWeakRef(object);
|
|
if (newWeakRef != nullptr) {
|
|
newWeakRef->IncWeakRefCount(this);
|
|
}
|
|
}
|
|
|
|
if (refs_ != nullptr) {
|
|
refs_->DecWeakRefCount(this);
|
|
}
|
|
|
|
refs_ = newWeakRef;
|
|
return *this;
|
|
}
|
|
|
|
template <typename T>
|
|
inline wptr<T> &wptr<T>::operator=(const wptr<T> &other)
|
|
{
|
|
if (other.refs_ != nullptr) {
|
|
other.refs_->IncWeakRefCount(this);
|
|
}
|
|
|
|
if (refs_ != nullptr) {
|
|
refs_->DecWeakRefCount(this);
|
|
}
|
|
|
|
refs_ = other.refs_;
|
|
return *this;
|
|
}
|
|
|
|
template <typename T>
|
|
inline wptr<T> &wptr<T>::operator=(const sptr<T> &other)
|
|
{
|
|
WeakRefCounter *newWeakRef = nullptr;
|
|
if (other.GetRefPtr() != nullptr) {
|
|
newWeakRef = other->CreateWeakRef(other.GetRefPtr());
|
|
if (newWeakRef != nullptr) {
|
|
newWeakRef->IncWeakRefCount(this);
|
|
}
|
|
}
|
|
|
|
if (refs_ != nullptr) {
|
|
refs_->DecWeakRefCount(this);
|
|
}
|
|
|
|
refs_ = newWeakRef;
|
|
return *this;
|
|
}
|
|
|
|
template <typename T>
|
|
template <typename O>
|
|
wptr<T> &wptr<T>::operator=(const wptr<O> &other)
|
|
{
|
|
if (other.refs_ != nullptr) {
|
|
other.refs_->IncWeakRefCount(this);
|
|
}
|
|
|
|
if (refs_ != nullptr) {
|
|
refs_->DecWeakRefCount(this);
|
|
}
|
|
|
|
refs_ = other.refs_;
|
|
return *this;
|
|
}
|
|
|
|
template <typename T>
|
|
template <typename O>
|
|
wptr<T> &wptr<T>::operator=(const sptr<O> &other)
|
|
{
|
|
WeakRefCounter *newWeakRef = nullptr;
|
|
if (other.GetRefPtr() != nullptr) {
|
|
newWeakRef = other->CreateWeakRef(other.GetRefPtr());
|
|
if (newWeakRef != nullptr) {
|
|
newWeakRef->IncWeakRefCount(this);
|
|
}
|
|
}
|
|
|
|
if (refs_ != nullptr) {
|
|
refs_->DecWeakRefCount(this);
|
|
}
|
|
|
|
refs_ = newWeakRef;
|
|
return *this;
|
|
}
|
|
|
|
template <typename T>
|
|
inline bool wptr<T>::operator==(const T *other) const
|
|
{
|
|
return GetRefPtr() == other;
|
|
}
|
|
|
|
template <typename T>
|
|
inline bool wptr<T>::operator==(const wptr<T> &other) const
|
|
{
|
|
return GetRefPtr() == other.GetRefPtr();
|
|
}
|
|
|
|
template <typename T>
|
|
inline bool wptr<T>::operator==(const sptr<T> &other) const
|
|
{
|
|
return GetRefPtr() == other.GetRefPtr();
|
|
}
|
|
|
|
template <typename T>
|
|
inline const sptr<T> wptr<T>::promote() const
|
|
{
|
|
return sptr<T>(refs_, true);
|
|
}
|
|
|
|
template <typename T>
|
|
inline wptr<T>::~wptr()
|
|
{
|
|
if (refs_ != nullptr) {
|
|
refs_->DecWeakRefCount(this);
|
|
}
|
|
}
|
|
|
|
} // namespace OHOS
|
|
|
|
#endif
|
|
|
|
/**@}*/
|