summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorilnurkh <[email protected]>2025-04-25 13:55:53 +0300
committerilnurkh <[email protected]>2025-04-25 14:44:41 +0300
commitc0533d88038a1fc7c4753c986e6c47bb4cbd21b7 (patch)
treea0f8a9a9258adc10804fe96aaca4f7c5a578d593
parentcecedbe2b29df37e09409fc2d15fb8211269d8b1 (diff)
GetRef in TPointerCommon
commit_hash:4149625a81c51af40642fe498a887608cc57305f
-rw-r--r--util/generic/ptr.cpp5
-rw-r--r--util/generic/ptr.h16
-rw-r--r--util/generic/ptr_ut.cpp29
3 files changed, 50 insertions, 0 deletions
diff --git a/util/generic/ptr.cpp b/util/generic/ptr.cpp
index b29baebc175..963dcd5160c 100644
--- a/util/generic/ptr.cpp
+++ b/util/generic/ptr.cpp
@@ -1,4 +1,5 @@
#include "ptr.h"
+#include "yexception.h"
#include <util/system/defaults.h>
#include <util/memory/alloc.h>
@@ -15,3 +16,7 @@ void TDelete::Destroy(void* t) noexcept {
}
TThrRefBase::~TThrRefBase() = default;
+
+[[noreturn]] void NDetail::NullDerefenceThrowImpl() {
+ ythrow yexception{} << "nullptr dereference";
+}
diff --git a/util/generic/ptr.h b/util/generic/ptr.h
index 625418ccdb0..cf28d0bfd2c 100644
--- a/util/generic/ptr.h
+++ b/util/generic/ptr.h
@@ -100,6 +100,10 @@ private:
static void DoDestroy(void* t) noexcept;
};
+namespace NDetail {
+ [[noreturn]] void NullDerefenceThrowImpl();
+} // namespace NDetail
+
template <class Base, class T>
class TPointerCommon {
public:
@@ -116,6 +120,18 @@ public:
return ptr;
}
+ inline typename std::add_lvalue_reference<T>::type GetRef() const {
+ T* ptr = AsT();
+ if (Y_UNLIKELY(!ptr)) {
+ NDetail::NullDerefenceThrowImpl();
+ }
+ if constexpr (std::is_void<T>::value) {
+ return;
+ } else {
+ return *ptr;
+ }
+ }
+
#ifndef __cpp_impl_three_way_comparison
template <class C>
inline bool operator==(const C& p) const noexcept {
diff --git a/util/generic/ptr_ut.cpp b/util/generic/ptr_ut.cpp
index 8f72cee5219..e6a4a7837c0 100644
--- a/util/generic/ptr_ut.cpp
+++ b/util/generic/ptr_ut.cpp
@@ -36,6 +36,7 @@ class TPointerTest: public TTestBase {
UNIT_TEST(TestRefCountedPtrsInHashSet);
UNIT_TEST(TestSharedPtrDowncast);
UNIT_TEST(TestStdCompatibility);
+ UNIT_TEST(TestGetRef);
UNIT_TEST_SUITE_END();
private:
@@ -91,6 +92,7 @@ private:
void TestRefCountedPtrsInHashSet();
void TestSharedPtrDowncast();
void TestStdCompatibility();
+ void TestGetRef();
};
UNIT_TEST_SUITE_REGISTRATION(TPointerTest);
@@ -962,3 +964,30 @@ void TPointerTest::TestStdCompatibility() {
UNIT_ASSERT_VALUES_EQUAL(ptr.get(), ptr.Get());
}
}
+
+void TPointerTest::TestGetRef() {
+ {
+ TSimpleSharedPtr<int> ptr = MakeSimpleShared<int>(5);
+ UNIT_ASSERT_TYPES_EQUAL(decltype(ptr.GetRef()), int&);
+ UNIT_ASSERT_VALUES_EQUAL(ptr.GetRef(), 5);
+ ptr.GetRef() += 5;
+ UNIT_ASSERT_VALUES_EQUAL(ptr.GetRef(), 10);
+ }
+ {
+ THolder<const int> ptr = MakeHolder<int>(5);
+ UNIT_ASSERT_TYPES_EQUAL(decltype(ptr.GetRef()), const int&);
+ UNIT_ASSERT_VALUES_EQUAL(ptr.GetRef(), 5);
+ }
+ {
+ THolder<const int> ptr;
+ UNIT_ASSERT_EXCEPTION(ptr.GetRef(), yexception);
+ }
+
+ {
+ THolder<void, TNoAction> ptr((void*)10);
+ UNIT_ASSERT_TYPES_EQUAL(decltype(ptr.GetRef()), void);
+ ptr.GetRef();
+ ptr = {};
+ UNIT_ASSERT_EXCEPTION(ptr.GetRef(), yexception);
+ }
+}