mirror of
https://github.com/espressif/openthread.git
synced 2026-07-28 06:37:46 +00:00
[common] add Ptr to use as base of OwnedPtr and RetainPtr (#7195)
This commit adds a new class `Ptr<Type>` which represents a wrapper over a raw pointer. This is then used as the base class of `OwnedPtr` and `RetainPtr` providing the common simple methods (avoiding repeating the same code in each smart pointter). The new `Ptr` class also adds overloads of `==` and `!=` allowing `Ptr` to be compared with a given raw pointer or another `Ptr` instance.
This commit is contained in:
committed by
Jonathan Hui
parent
2d16fa25e4
commit
4acdf1d0fb
@@ -415,6 +415,7 @@ openthread_core_files = [
|
||||
"common/owned_ptr.hpp",
|
||||
"common/owning_list.hpp",
|
||||
"common/pool.hpp",
|
||||
"common/ptr_wrapper.hpp",
|
||||
"common/random.hpp",
|
||||
"common/random_manager.cpp",
|
||||
"common/random_manager.hpp",
|
||||
|
||||
@@ -449,6 +449,7 @@ HEADERS_COMMON = \
|
||||
common/owned_ptr.hpp \
|
||||
common/owning_list.hpp \
|
||||
common/pool.hpp \
|
||||
common/ptr_wrapper.hpp \
|
||||
common/random.hpp \
|
||||
common/random_manager.hpp \
|
||||
common/retain_ptr.hpp \
|
||||
|
||||
@@ -36,8 +36,7 @@
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "common/ptr_wrapper.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
||||
@@ -52,17 +51,16 @@ namespace ot {
|
||||
* @tparam Type The pointer type.
|
||||
*
|
||||
*/
|
||||
template <class Type> class OwnedPtr
|
||||
template <class Type> class OwnedPtr : public Ptr<Type>
|
||||
{
|
||||
using Ptr<Type>::mPointer;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This is the default constructor for `OwnedPtr` initializing it as null.
|
||||
*
|
||||
*/
|
||||
OwnedPtr(void)
|
||||
: mPointer(nullptr)
|
||||
{
|
||||
}
|
||||
OwnedPtr(void) = default;
|
||||
|
||||
/**
|
||||
* This constructor initializes the `OwnedPtr` with a given pointer.
|
||||
@@ -73,7 +71,7 @@ public:
|
||||
*
|
||||
*/
|
||||
explicit OwnedPtr(Type *aPointer)
|
||||
: mPointer(aPointer)
|
||||
: Ptr<Type>(aPointer)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -99,31 +97,6 @@ public:
|
||||
*/
|
||||
~OwnedPtr(void) { Delete(); }
|
||||
|
||||
/**
|
||||
* This method indicates whether the `OwnedPtr` is null or not.
|
||||
*
|
||||
* @retval TRUE The `OwnedPtr` is null.
|
||||
* @retval FALSE The `OwnedPtr` is not null.
|
||||
*
|
||||
*/
|
||||
bool IsNull(void) const { return (mPointer == nullptr); }
|
||||
|
||||
/**
|
||||
* This method gets the raw pointer to the object owned by `OwnedPtr`.
|
||||
*
|
||||
* @returns The raw pointer to the object owned by `OwnedPtr` or `nullptr` if none.
|
||||
*
|
||||
*/
|
||||
Type *Get(void) { return mPointer; }
|
||||
|
||||
/**
|
||||
* This method gets the raw pointer to the object owned by `OwnedPtr`.
|
||||
*
|
||||
* @returns The raw pointer to the object owned by `OwnedPtr` or `nullptr` if none.
|
||||
*
|
||||
*/
|
||||
const Type *Get(void) const { return mPointer; }
|
||||
|
||||
/**
|
||||
* This method frees the owned object (if any).
|
||||
*
|
||||
@@ -171,42 +144,6 @@ public:
|
||||
return pointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method overloads the `->` dereference operator and returns a pointer to the object owned by `OwnedPtr`.
|
||||
*
|
||||
* @returns A pointer to owned object or `nullptr` if none.
|
||||
*
|
||||
*/
|
||||
Type *operator->(void) { return mPointer; }
|
||||
|
||||
/**
|
||||
* This method overloads the `->` dereference operator and returns a pointer to the object owned by `OwnedPtr`.
|
||||
*
|
||||
* @returns A pointer to owned object or `nullptr` if none.
|
||||
*
|
||||
*/
|
||||
const Type *operator->(void)const { return mPointer; }
|
||||
|
||||
/**
|
||||
* This method overloads the `*` dereference operator and returns a reference to the object owned by `OwnedPtr`.
|
||||
*
|
||||
* The behavior is undefined if `IsNull() == true`.
|
||||
*
|
||||
* @returns A reference to the object owned by `OwnedPtr`.
|
||||
*
|
||||
*/
|
||||
Type &operator*(void) { return *mPointer; }
|
||||
|
||||
/**
|
||||
* This method overloads the `*` dereference operator and returns a reference to the object owned by `OwnedPtr`.
|
||||
*
|
||||
* The behavior is undefined if `IsNull() == true`.
|
||||
*
|
||||
* @returns A reference to the object owned by `OwnedPtr`.
|
||||
*
|
||||
*/
|
||||
const Type &operator*(void)const { return *mPointer; }
|
||||
|
||||
/**
|
||||
* This method overload the assignment operator `=` to replace the object owned by the `OwnedPtr` with another one
|
||||
* using move semantics.
|
||||
@@ -238,8 +175,6 @@ private:
|
||||
mPointer->Free();
|
||||
}
|
||||
}
|
||||
|
||||
Type *mPointer;
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (c) 2021, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file includes definitions for a pointer wrapper.
|
||||
*/
|
||||
|
||||
#ifndef PTR_WRAPPER_HPP_
|
||||
#define PTR_WRAPPER_HPP_
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ot {
|
||||
|
||||
/**
|
||||
* This template class represents a wrapper over a pointer.
|
||||
*
|
||||
* This is intended as base class of `OwnedPtr` or `RetainPtr` providing common simple methods.
|
||||
*
|
||||
* @tparam Type The pointer type.
|
||||
*
|
||||
*/
|
||||
template <class Type> class Ptr
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This is the default constructor for `Ptr` initializing it as null.
|
||||
*
|
||||
*/
|
||||
Ptr(void)
|
||||
: mPointer(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor initializes the `Ptr` with a given pointer.
|
||||
*
|
||||
* @param[in] aPointer A pointer to initialize with.
|
||||
*
|
||||
*/
|
||||
explicit Ptr(Type *aPointer)
|
||||
: mPointer(aPointer)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method indicates whether the `Ptr` is null or not.
|
||||
*
|
||||
* @retval TRUE The `Ptr` is null.
|
||||
* @retval FALSE The `Ptr` is not null.
|
||||
*
|
||||
*/
|
||||
bool IsNull(void) const { return (mPointer == nullptr); }
|
||||
|
||||
/**
|
||||
* This method gets the wrapped pointer.
|
||||
*
|
||||
* @returns The wrapped pointer.
|
||||
*
|
||||
*/
|
||||
Type *Get(void) { return mPointer; }
|
||||
|
||||
/**
|
||||
* This method gets the wrapped pointer.
|
||||
*
|
||||
* @returns The wrapped pointer.
|
||||
*
|
||||
*/
|
||||
const Type *Get(void) const { return mPointer; }
|
||||
|
||||
/**
|
||||
* This method overloads the `->` dereference operator and returns the pointer.
|
||||
*
|
||||
* @returns The wrapped pointer.
|
||||
*
|
||||
*/
|
||||
Type *operator->(void) { return mPointer; }
|
||||
|
||||
/**
|
||||
* This method overloads the `->` dereference operator and returns the pointer.
|
||||
*
|
||||
* @returns The wrapped pointer.
|
||||
*
|
||||
*/
|
||||
const Type *operator->(void)const { return mPointer; }
|
||||
|
||||
/**
|
||||
* This method overloads the `*` dereference operator and returns a reference to the pointed object.
|
||||
*
|
||||
* The behavior is undefined if `IsNull() == true`.
|
||||
*
|
||||
* @returns A reference to the pointed object.
|
||||
*
|
||||
*/
|
||||
Type &operator*(void) { return *mPointer; }
|
||||
|
||||
/**
|
||||
* This method overloads the `*` dereference operator and returns a reference to the pointed object.
|
||||
*
|
||||
* The behavior is undefined if `IsNull() == true`.
|
||||
*
|
||||
* @returns A reference to the pointed object.
|
||||
*
|
||||
*/
|
||||
const Type &operator*(void)const { return *mPointer; }
|
||||
|
||||
/**
|
||||
* This method overloads the operator `==` to compare the `Ptr` with a given pointer.
|
||||
*
|
||||
* @param[in] aPointer The pointer to compare with.
|
||||
*
|
||||
* @retval TRUE If `Ptr` is equal to @p aPointer.
|
||||
* @retval FLASE If `Ptr` is not equal to @p aPointer.
|
||||
*
|
||||
*/
|
||||
bool operator==(const Type *aPointer) const { return (mPointer == aPointer); }
|
||||
|
||||
/**
|
||||
* This method overloads the operator `!=` to compare the `Ptr` with a given pointer.
|
||||
*
|
||||
* @param[in] aPointer The pointer to compare with.
|
||||
*
|
||||
* @retval TRUE If `Ptr` is not equal to @p aPointer.
|
||||
* @retval FLASE If `Ptr` is equal to @p aPointer.
|
||||
*
|
||||
*/
|
||||
bool operator!=(const Type *aPointer) const { return (mPointer != aPointer); }
|
||||
|
||||
/**
|
||||
* This method overloads the operator `==` to compare the `Ptr` with another `Ptr`.
|
||||
*
|
||||
* @param[in] aOther The other `Ptr` to compare with.
|
||||
*
|
||||
* @retval TRUE If `Ptr` is equal to @p aOther.
|
||||
* @retval FLASE If `Ptr` is not equal to @p aOther.
|
||||
*
|
||||
*/
|
||||
bool operator==(const Ptr &aOther) const { return (mPointer == aOther.mPointer); }
|
||||
|
||||
/**
|
||||
* This method overloads the operator `!=` to compare the `Ptr` with another `Ptr`.
|
||||
*
|
||||
* @param[in] aOther The other `Ptr` to compare with.
|
||||
*
|
||||
* @retval TRUE If `Ptr` is not equal to @p aOther.
|
||||
* @retval FLASE If `Ptr` is equal to @p aOther.
|
||||
*
|
||||
*/
|
||||
bool operator!=(const Ptr &aOther) const { return (mPointer != aOther.mPointer); }
|
||||
|
||||
protected:
|
||||
Type *mPointer;
|
||||
};
|
||||
|
||||
} // namespace ot
|
||||
|
||||
#endif // PTR_WRAPPER_HPP_
|
||||
@@ -36,8 +36,7 @@
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "common/ptr_wrapper.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
||||
@@ -56,17 +55,16 @@ namespace ot {
|
||||
* @tparam Type The pointer type.
|
||||
*
|
||||
*/
|
||||
template <class Type> class RetainPtr
|
||||
template <class Type> class RetainPtr : public Ptr<Type>
|
||||
{
|
||||
using Ptr<Type>::mPointer;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This is the default constructor for `RetainPtr` initializing it as null.
|
||||
*
|
||||
*/
|
||||
RetainPtr(void)
|
||||
: mPointer(nullptr)
|
||||
{
|
||||
}
|
||||
RetainPtr(void) = default;
|
||||
|
||||
/**
|
||||
* This constructor initializes the `RetainPtr` with a given pointer.
|
||||
@@ -77,7 +75,7 @@ public:
|
||||
*
|
||||
*/
|
||||
explicit RetainPtr(Type *aPointer)
|
||||
: mPointer(aPointer)
|
||||
: Ptr<Type>(aPointer)
|
||||
{
|
||||
IncrementRetainCount();
|
||||
}
|
||||
@@ -89,7 +87,7 @@ public:
|
||||
*
|
||||
*/
|
||||
RetainPtr(const RetainPtr &aOther)
|
||||
: mPointer(aOther.mPointer)
|
||||
: Ptr<Type>(aOther.mPointer)
|
||||
{
|
||||
IncrementRetainCount();
|
||||
}
|
||||
@@ -103,31 +101,6 @@ public:
|
||||
*/
|
||||
~RetainPtr(void) { DecrementRetainCount(); }
|
||||
|
||||
/**
|
||||
* This method indicates whether the `RetainPtr` is null or not.
|
||||
*
|
||||
* @retval TRUE The `RetainPtr` is null.
|
||||
* @retval FALSE The `RetainPtr` is not null.
|
||||
*
|
||||
*/
|
||||
bool IsNull(void) const { return (mPointer == nullptr); }
|
||||
|
||||
/**
|
||||
* This method gets the raw pointer to the object managed by `RetainPtr`.
|
||||
*
|
||||
* @returns The raw pointer to the object managed by `RetainPtr` or `nullptr` if none.
|
||||
*
|
||||
*/
|
||||
Type *Get(void) { return mPointer; }
|
||||
|
||||
/**
|
||||
* This method gets the raw pointer to the object managed by `RetainPtr`.
|
||||
*
|
||||
* @returns The raw pointer to the object managed by `RetainPtr` or `nullptr` if none.
|
||||
*
|
||||
*/
|
||||
const Type *Get(void) const { return mPointer; }
|
||||
|
||||
/**
|
||||
* This method replaces the managed object by `RetainPtr` with a new one.
|
||||
*
|
||||
@@ -164,56 +137,20 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* This method overloads the `->` dereference operator and returns a pointer to the object managed by `RetainPtr`.
|
||||
*
|
||||
* @returns A pointer to managed object or `nullptr` if none.
|
||||
*
|
||||
*/
|
||||
Type *operator->(void) { return mPointer; }
|
||||
|
||||
/**
|
||||
* This method overloads the `->` dereference operator and returns a pointer to the object managed by `RetainPtr`.
|
||||
*
|
||||
* @returns A pointer to managed object or `nullptr` if none.
|
||||
*
|
||||
*/
|
||||
const Type *operator->(void)const { return mPointer; }
|
||||
|
||||
/**
|
||||
* This method overloads the `*` dereference operator and returns a reference to the object managed by `RetainPtr`.
|
||||
*
|
||||
* The behavior is undefined if `IsNull() == true`.
|
||||
*
|
||||
* @returns A reference to the object managed by `RetainPtr`.
|
||||
*
|
||||
*/
|
||||
Type &operator*(void) { return *mPointer; }
|
||||
|
||||
/**
|
||||
* This method overloads the `*` dereference operator and returns a reference to the object managed by `RetainPtr`.
|
||||
*
|
||||
* The behavior is undefined if `IsNull() == true`.
|
||||
*
|
||||
* @returns A reference to the object managed by `RetainPtr`.
|
||||
*
|
||||
*/
|
||||
const Type &operator*(void)const { return *mPointer; }
|
||||
|
||||
/**
|
||||
* This method overload assignment operator `=` .
|
||||
* This method overloads the assignment operator `=`.
|
||||
*
|
||||
* The `RetainPtr` first frees its current managed object (if there is any and it is different from @p aOther)
|
||||
* before taking over the ownership of the object from @p aOther. This method correctly handles a self assignment
|
||||
* (i.e., assigning the pointer to itself).
|
||||
*
|
||||
* @param[in] aOther A reference to an `OwendPtr`.
|
||||
* @param[in] aOther A reference to another `RetainPtr`.
|
||||
*
|
||||
* @returns A reference to this `RetainPtr`.
|
||||
*
|
||||
*/
|
||||
RetainPtr &operator=(RetainPtr &aOther)
|
||||
RetainPtr &operator=(const RetainPtr &aOther)
|
||||
{
|
||||
Reset(aOther.Get());
|
||||
Reset(aOther.mPointer);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -233,8 +170,6 @@ private:
|
||||
mPointer->Free();
|
||||
}
|
||||
}
|
||||
|
||||
Type *mPointer;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -67,11 +67,14 @@ void VerifyPointer(const PointerType &aPointer,
|
||||
{
|
||||
VerifyOrQuit(aPointer.IsNull());
|
||||
VerifyOrQuit(aPointer.Get() == nullptr);
|
||||
VerifyOrQuit(aPointer == nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrQuit(!aPointer.IsNull());
|
||||
VerifyOrQuit(aPointer.Get() == aObject);
|
||||
VerifyOrQuit(aPointer == aObject);
|
||||
VerifyOrQuit(aPointer != nullptr);
|
||||
|
||||
VerifyOrQuit(!aPointer->WasFreed());
|
||||
VerifyOrQuit(!(*aPointer).WasFreed());
|
||||
@@ -81,6 +84,8 @@ void VerifyPointer(const PointerType &aPointer,
|
||||
VerifyOrQuit(aObject->GetRetainCount() == aRetainCount);
|
||||
}
|
||||
}
|
||||
|
||||
VerifyOrQuit(aPointer == aPointer);
|
||||
}
|
||||
|
||||
void TestOwnedPtr(void)
|
||||
@@ -388,27 +393,35 @@ void TestRetainPtr(void)
|
||||
VerifyPointer(ptr2, &obj2, 1);
|
||||
VerifyPointer(ptr3, nullptr);
|
||||
|
||||
VerifyOrQuit(ptr1 != ptr2);
|
||||
VerifyOrQuit(ptr1 != ptr3);
|
||||
VerifyOrQuit(ptr2 != ptr3);
|
||||
|
||||
// Set from non-null (ptr1) to non-null (ptr2)
|
||||
ptr2 = ptr1;
|
||||
VerifyPointer(ptr1, &obj1, 2);
|
||||
VerifyPointer(ptr2, &obj1, 2);
|
||||
VerifyOrQuit(obj2.WasFreed());
|
||||
VerifyOrQuit(ptr1 == ptr2);
|
||||
|
||||
// Set from null (ptr3) to non-null (ptr1)
|
||||
ptr1 = ptr3;
|
||||
VerifyPointer(ptr1, nullptr);
|
||||
VerifyPointer(ptr3, nullptr);
|
||||
VerifyPointer(ptr2, &obj1, 1);
|
||||
VerifyOrQuit(ptr1 == ptr3);
|
||||
|
||||
// Move from null (ptr1) to null (ptr3)
|
||||
ptr3 = ptr1;
|
||||
VerifyPointer(ptr1, nullptr);
|
||||
VerifyPointer(ptr3, nullptr);
|
||||
VerifyOrQuit(ptr1 == ptr3);
|
||||
|
||||
// Move from non-null (ptr2) to null (ptr3)
|
||||
ptr3 = ptr2;
|
||||
VerifyPointer(ptr2, &obj1, 2);
|
||||
VerifyPointer(ptr3, &obj1, 2);
|
||||
VerifyOrQuit(ptr2 == ptr3);
|
||||
}
|
||||
|
||||
VerifyOrQuit(obj1.WasFreed());
|
||||
|
||||
Reference in New Issue
Block a user