-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
119 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/** | ||
* Copyright 2024 Nokia | ||
* Licensed under the BSD 3 Clause license | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
// *********************************************************************************************** | ||
// - ISSUE: | ||
// . c++ mem bugs are 1 of the most challenge (eg use Rust to replace c++) | ||
// - REQ: this class is to impl | ||
// . valid ptr: by construct | ||
// . valid cp/mv ptr: between valid type (same type, base-derive, any<->void) | ||
// . valid ptr lifecycle: by shared_ptr | ||
// . valid ptr array | ||
// . suggest any class ensure mem-safe (like MT safe) | ||
// *********************************************************************************************** | ||
#pragma once | ||
|
||
#include <functional> | ||
#include <memory> | ||
#include <iostream> | ||
|
||
using namespace std; | ||
|
||
namespace RLib | ||
{ | ||
// *********************************************************************************************** | ||
class SafePtr | ||
{ | ||
public: | ||
// new | ||
template<typename T> | ||
SafePtr(std::shared_ptr<T> aT) : pT_(static_pointer_cast<void>(aT)), originType_(&typeid(T)) {} // expand but safe construct | ||
SafePtr() = default; | ||
|
||
template<typename To = void> To* get() | ||
{ | ||
return (&typeid(To) == originType_ || is_same<To, void>::value) | ||
? static_pointer_cast<To>(pT_).get() | ||
: nullptr; | ||
} | ||
|
||
const type_info* originType() const { return originType_; } | ||
private: | ||
// ------------------------------------------------------------------------------------------- | ||
std::shared_ptr<void> pT_; | ||
const type_info* originType_ = nullptr; // can't static since derived from T | ||
}; | ||
|
||
} // namespace | ||
// *********************************************************************************************** | ||
// YYYY-MM-DD Who v)Modification Description | ||
// .......... ......... ....................................................................... | ||
// 2024-01-30 CSZ 1)create | ||
// *********************************************************************************************** | ||
// - T not ref/ptr/const? | ||
// - higher perf | ||
// - SafeRef? or like this? | ||
// - why | ||
// . safe construct | ||
// . safe copy/= | ||
// . safe array | ||
// . struct ptr/ref member shall be SafePtr | ||
// . safe owner (avoid wild ptr, use-after-free) | ||
// . how about class' this? | ||
// . worth? | ||
// - all classes shall mem-safe | ||
// . type_info* instead of hash_code? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/** | ||
* Copyright 2024 Nokia. All rights reserved. | ||
* Licensed under the BSD 3 Clause license | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
// *********************************************************************************************** | ||
#include <gtest/gtest.h> | ||
|
||
#include "SafePtr.hpp" | ||
|
||
namespace RLib | ||
{ | ||
#define NEW_CP_MV_GET | ||
// *********************************************************************************************** | ||
TEST(SafePtrTest, GOLD_construct_get) | ||
{ | ||
SafePtr t1(make_shared<int>(42)); | ||
EXPECT_EQ(42, *(t1.get<int>())) << "REQ: valid construct & get (original type)"; | ||
EXPECT_EQ(t1.get(), t1.get<int>()) << "REQ: valid get (void)"; | ||
EXPECT_EQ(nullptr, t1.get<unsigned>()) << "REQ: invalid get (diff type)"; | ||
} | ||
TEST(SafePtrTest, GOLD_cp_get) | ||
{ | ||
SafePtr t1(make_shared<int>(42)); | ||
SafePtr t2 = t1; | ||
EXPECT_EQ(t1.get(), t2.get<int>()) << "REQ: valid cp & get (original type)"; | ||
EXPECT_EQ(t2.get(), t2.get<int>()) << "REQ: valid get (void)"; | ||
EXPECT_EQ(nullptr, t2.get<bool>()) << "REQ: invalid get (diff type)"; | ||
} | ||
TEST(SafePtrTest, GOLD_mv_get) | ||
{ | ||
SafePtr t1; | ||
EXPECT_EQ(nullptr, t1.get()) << "REQ: construct null & get it"; | ||
EXPECT_EQ(nullptr, t1.get<int>()) << "REQ: invalid get"; | ||
|
||
SafePtr t2(make_shared<char>('a')); | ||
t1 = t2; | ||
EXPECT_EQ('a', *(t1.get<char>())) << "REQ: valid get (original type)"; | ||
|
||
SafePtr t3(make_shared<bool>(true)); | ||
t1 = t3; | ||
EXPECT_TRUE(*(t1.get<bool>())) << "REQ: valid get (original type)"; | ||
EXPECT_EQ('a', *(t2.get<char>())) << "REQ: replacement not impact original"; | ||
|
||
t3 = SafePtr(); | ||
EXPECT_EQ(nullptr, t3.get()) << "REQ: can reset SafePtr"; | ||
EXPECT_TRUE(*(t1.get<bool>())) << "REQ: lifecycle valid"; | ||
} | ||
|
||
} // namespace |