Skip to content

Commit

Permalink
SafePtr: create
Browse files Browse the repository at this point in the history
  • Loading branch information
fchn289 committed Feb 5, 2024
1 parent d895b1b commit ccb59e1
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/log/UniCoutLog.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// - CORE:
// . cout
//
// - MT safe: NO!!! since (static) member; so shall NOT cross-thread use
// - MT safe: NO!!! since (static) nLogLine_; so shall NOT cross-thread use
// ***********************************************************************************************
#ifndef UNI_COUT_LOG_HPP_
#define UNI_COUT_LOG_HPP_
Expand Down
2 changes: 1 addition & 1 deletion src/log/UniSmartLog.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
// - CORE:
// . smartLog_
//
// - MT safe: NO!!! since (static) member; so shall NOT cross-thread use
// - MT safe: NO!!! since (static) logStore_; so shall NOT cross-thread use
// ***********************************************************************************************
#ifndef UNI_SMART_LOG_HPP_
#define UNI_SMART_LOG_HPP_
Expand Down
67 changes: 67 additions & 0 deletions src/safe_mem/SafePtr.hpp
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?
50 changes: 50 additions & 0 deletions ut/safe_mem/SafePtrTest.cpp
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

0 comments on commit ccb59e1

Please sign in to comment.