aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrobot-piglet <robot-piglet@yandex-team.com>2024-09-03 16:13:54 +0300
committerrobot-piglet <robot-piglet@yandex-team.com>2024-09-03 16:23:38 +0300
commit4a23bc2f0f1ebf6cfcf1bae08e95f55f759c9b22 (patch)
treee065cb5399b54fe2bbb3357ec63d38e56a81470b
parent3da5a68ec3c329240e89bd0ed8c1c39e4359a693 (diff)
downloadydb-4a23bc2f0f1ebf6cfcf1bae08e95f55f759c9b22.tar.gz
Intermediate changes
-rw-r--r--library/cpp/yt/misc/non_null_ptr-inl.h49
-rw-r--r--library/cpp/yt/misc/non_null_ptr.h76
-rw-r--r--library/cpp/yt/misc/unittests/non_null_ptr_ut.cpp102
-rw-r--r--library/cpp/yt/misc/unittests/ya.make1
4 files changed, 228 insertions, 0 deletions
diff --git a/library/cpp/yt/misc/non_null_ptr-inl.h b/library/cpp/yt/misc/non_null_ptr-inl.h
new file mode 100644
index 0000000000..a14b1e9302
--- /dev/null
+++ b/library/cpp/yt/misc/non_null_ptr-inl.h
@@ -0,0 +1,49 @@
+#pragma once
+#ifndef NON_NULL_PTR_H_
+#error "Direct inclusion of this file is not allowed, include helpers.h"
+// For the sake of sane code completion.
+#include "non_null_ptr.h"
+#endif
+
+#include <library/cpp/yt/assert/assert.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+TNonNullPtrBase<T>::TNonNullPtrBase(T* ptr) noexcept
+ : Ptr_(ptr)
+{
+ YT_VERIFY(ptr);
+}
+
+template <class T>
+T* TNonNullPtrBase<T>::operator->() const noexcept
+{
+ return Ptr_;
+}
+
+template <class T>
+T& TNonNullPtrBase<T>::operator*() const noexcept
+{
+ return *Ptr_;
+}
+
+template <class T>
+TNonNullPtrBase<T>::TNonNullPtrBase() noexcept
+ : Ptr_(nullptr)
+{ }
+
+template <class T>
+TNonNullPtr<T> GetPtr(T& ref) noexcept
+{
+ TNonNullPtr<T> ptr;
+ ptr.Ptr_ = &ref;
+
+ return ptr;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/misc/non_null_ptr.h b/library/cpp/yt/misc/non_null_ptr.h
new file mode 100644
index 0000000000..0005e4edb6
--- /dev/null
+++ b/library/cpp/yt/misc/non_null_ptr.h
@@ -0,0 +1,76 @@
+#pragma once
+
+#include "concepts.h"
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+// We have one really strange rule in our codestyle - mutable arguments are passed by pointer.
+// But if you are not a fan of making your life indefinite,
+// you can use this helper, that will validate that pointer you pass is not null.
+template <class T>
+class TNonNullPtr;
+
+template <class T>
+class TNonNullPtrBase
+{
+public:
+ TNonNullPtrBase(T* ptr) noexcept;
+ TNonNullPtrBase(const TNonNullPtrBase& other) = default;
+
+ TNonNullPtrBase(std::nullptr_t) = delete;
+ TNonNullPtrBase operator=(const TNonNullPtrBase&) = delete;
+
+ T* operator->() const noexcept;
+ T& operator*() const noexcept;
+
+protected:
+ T* Ptr_;
+
+ TNonNullPtrBase() noexcept;
+};
+
+template <class T>
+TNonNullPtr<T> GetPtr(T& ref) noexcept;
+
+template <class T>
+class TNonNullPtr
+ : public TNonNullPtrBase<T>
+{
+ using TConstPtr = TNonNullPtr<const T>;
+ friend TConstPtr;
+
+ using TNonNullPtrBase<T>::TNonNullPtrBase;
+
+ friend TNonNullPtr<T> GetPtr<T>(T& ref) noexcept;
+};
+
+// NB(pogorelov): Method definitions placed in .h file (instead of -inl.h) because of clang16 bug.
+// TODO(pogorelov): Move method definitions to helpers-inl.h when new clang will be used.
+template <CConst T>
+class TNonNullPtr<T>
+ : public TNonNullPtrBase<T>
+{
+ using TMutPtr = TNonNullPtr<std::remove_const_t<T>>;
+
+ using TNonNullPtrBase<T>::TNonNullPtrBase;
+
+ friend TNonNullPtr<T> GetPtr<T>(T& ref) noexcept;
+
+public:
+ TNonNullPtr(TMutPtr mutPtr) noexcept
+ : TNonNullPtrBase<T>()
+ {
+ TNonNullPtrBase<T>::Ptr_ = mutPtr.Ptr_;
+ }
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
+
+#define NON_NULL_PTR_H_
+#include "non_null_ptr-inl.h"
+#undef NON_NULL_PTR_H_
diff --git a/library/cpp/yt/misc/unittests/non_null_ptr_ut.cpp b/library/cpp/yt/misc/unittests/non_null_ptr_ut.cpp
new file mode 100644
index 0000000000..a6903edc40
--- /dev/null
+++ b/library/cpp/yt/misc/unittests/non_null_ptr_ut.cpp
@@ -0,0 +1,102 @@
+#include <library/cpp/testing/gtest/gtest.h>
+
+#include <library/cpp/yt/misc/non_null_ptr.h>
+
+namespace NYT {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+
+enum EFuncResult {
+ Base,
+ ConstBase,
+ Derived,
+ ConstDerived,
+};
+
+enum EBinaryFuncResult {
+ Ok,
+ NotOk,
+};
+
+struct TBase
+{ };
+
+struct TDerived
+ : public TBase
+{ };
+
+EFuncResult Foo(TNonNullPtr<TBase> /*base*/)
+{
+ return EFuncResult::Base;
+}
+
+EFuncResult Foo(TNonNullPtr<const TBase> /*base*/)
+{
+ return EFuncResult::ConstBase;
+}
+
+EFuncResult Foo(TNonNullPtr<TDerived> /*derived*/)
+{
+ return EFuncResult::Derived;
+}
+
+EFuncResult Foo(TNonNullPtr<const TDerived> /*derived*/)
+{
+ return EFuncResult::ConstDerived;
+}
+
+[[maybe_unused]] EBinaryFuncResult Foo(int* /*derived*/)
+{
+ return EBinaryFuncResult::NotOk;
+}
+
+EBinaryFuncResult Foo(TNonNullPtr<int> /*derived*/)
+{
+ return EBinaryFuncResult::Ok;
+}
+
+EBinaryFuncResult Bar(TNonNullPtr<const int> /*arg*/)
+{
+ return EBinaryFuncResult::Ok;
+}
+
+EBinaryFuncResult Baz(TNonNullPtr<int> /*arg*/)
+{
+ return EBinaryFuncResult::Ok;
+}
+
+TEST(TNonNullPtrTest, Simple)
+{
+ TDerived derived{};
+ const auto& constDerived = derived;
+ EXPECT_EQ(EFuncResult::Derived, Foo(GetPtr(derived)));
+ EXPECT_EQ(EFuncResult::ConstDerived, Foo(GetPtr(constDerived)));
+
+ TBase base{};
+ const auto& constBase = base;
+ EXPECT_EQ(EFuncResult::Base, Foo(GetPtr(base)));
+ EXPECT_EQ(EFuncResult::ConstBase, Foo(GetPtr(constBase)));
+
+ int i{};
+ EXPECT_EQ(EBinaryFuncResult::Ok, Foo(GetPtr(i)));
+}
+
+TEST(TNonNullPtrTest, CastToConst)
+{
+ int i{};
+
+ EXPECT_EQ(EBinaryFuncResult::Ok, Bar(GetPtr(i)));
+}
+
+TEST(TNonNullPtrTest, ConstructionFromRawPointer)
+{
+ int i{};
+
+ EXPECT_EQ(EBinaryFuncResult::Ok, Baz(&i));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+} // namespace NYT
diff --git a/library/cpp/yt/misc/unittests/ya.make b/library/cpp/yt/misc/unittests/ya.make
index 611edd7217..5a071c887c 100644
--- a/library/cpp/yt/misc/unittests/ya.make
+++ b/library/cpp/yt/misc/unittests/ya.make
@@ -5,6 +5,7 @@ INCLUDE(${ARCADIA_ROOT}/library/cpp/yt/ya_cpp.make.inc)
SRCS(
enum_ut.cpp
guid_ut.cpp
+ non_null_ptr_ut.cpp
preprocessor_ut.cpp
strong_typedef_ut.cpp
)