diff options
author | Anton Samokhvalov <pg83@yandex.ru> | 2022-02-10 16:45:17 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:17 +0300 |
commit | d3a398281c6fd1d3672036cb2d63f842d2cb28c5 (patch) | |
tree | dd4bd3ca0f36b817e96812825ffaf10d645803f2 /util/generic/ptr.h | |
parent | 72cb13b4aff9bc9cf22e49251bc8fd143f82538f (diff) | |
download | ydb-d3a398281c6fd1d3672036cb2d63f842d2cb28c5.tar.gz |
Restoring authorship annotation for Anton Samokhvalov <pg83@yandex.ru>. Commit 2 of 2.
Diffstat (limited to 'util/generic/ptr.h')
-rw-r--r-- | util/generic/ptr.h | 1210 |
1 files changed, 605 insertions, 605 deletions
diff --git a/util/generic/ptr.h b/util/generic/ptr.h index e71cda285a..19db0e3ec5 100644 --- a/util/generic/ptr.h +++ b/util/generic/ptr.h @@ -1,22 +1,22 @@ #pragma once - + #include "fwd.h" #include "utility.h" #include "intrlist.h" #include "refcount.h" #include "typetraits.h" -#include "singleton.h" - +#include "singleton.h" + #include <utility> - -#include <util/system/yassert.h> -#include <util/system/defaults.h> - + +#include <util/system/yassert.h> +#include <util/system/defaults.h> + template <class T, class U> using TGuardConversion = typename std::enable_if_t<std::is_convertible<U*, T*>::value>; -template <class T> -inline void AssertTypeComplete() { +template <class T> +inline void AssertTypeComplete() { // If compiler triggers this error from destructor of your class with // smart pointer, then may be you should move the destructor definition // to the .cpp file, where type T have full definition. @@ -25,213 +25,213 @@ inline void AssertTypeComplete() { // undefined behavior (missing destructor call/corrupted memory manager). // 'sizeof' is used to trigger compile-time error. static_assert(sizeof(T) != 0, "Type must be complete"); -} - -template <class T> -inline void CheckedDelete(T* t) { - AssertTypeComplete<T>(); - +} + +template <class T> +inline void CheckedDelete(T* t) { + AssertTypeComplete<T>(); + delete t; } -template <class T> -inline void CheckedArrayDelete(T* t) { - AssertTypeComplete<T>(); - - delete[] t; +template <class T> +inline void CheckedArrayDelete(T* t) { + AssertTypeComplete<T>(); + + delete[] t; } class TNoAction { -public: - template <class T> +public: + template <class T> static inline void Destroy(T*) noexcept { - } + } }; -class TDelete { -public: - template <class T> +class TDelete { +public: + template <class T> static inline void Destroy(T* t) noexcept { - CheckedDelete(t); - } - - /* + CheckedDelete(t); + } + + /* * special handling for nullptr - call nothing */ static inline void Destroy(std::nullptr_t) noexcept { } /* - * special handling for void* - call ::operator delete() - */ + * special handling for void* - call ::operator delete() + */ static void Destroy(void* t) noexcept; -}; - -class TDeleteArray { -public: - template <class T> +}; + +class TDeleteArray { +public: + template <class T> static inline void Destroy(T* t) noexcept { - CheckedArrayDelete(t); - } -}; - -class TDestructor { -public: - template <class T> + CheckedArrayDelete(t); + } +}; + +class TDestructor { +public: + template <class T> static inline void Destroy(T* t) noexcept { - (void)t; - t->~T(); - } -}; - -class TFree { -public: - template <class T> + (void)t; + t->~T(); + } +}; + +class TFree { +public: + template <class T> static inline void Destroy(T* t) noexcept { - DoDestroy((void*)t); - } - -private: - /* - * we do not want dependancy on cstdlib here... - */ + DoDestroy((void*)t); + } + +private: + /* + * we do not want dependancy on cstdlib here... + */ static void DoDestroy(void* t) noexcept; -}; - -template <class Base, class T> -class TPointerCommon { -public: +}; + +template <class Base, class T> +class TPointerCommon { +public: using TValueType = T; inline T* operator->() const noexcept { T* ptr = AsT(); Y_ASSERT(ptr); return ptr; - } - -#ifndef __cpp_impl_three_way_comparison - template <class C> + } + +#ifndef __cpp_impl_three_way_comparison + template <class C> inline bool operator==(const C& p) const noexcept { - return (p == AsT()); - } - - template <class C> + return (p == AsT()); + } + + template <class C> inline bool operator!=(const C& p) const noexcept { - return (p != AsT()); - } -#endif - + return (p != AsT()); + } +#endif + inline explicit operator bool() const noexcept { return nullptr != AsT(); - } - -protected: + } + +protected: inline T* AsT() const noexcept { - return (static_cast<const Base*>(this))->Get(); - } - + return (static_cast<const Base*>(this))->Get(); + } + static inline T* DoRelease(T*& t) noexcept { - T* ret = t; + T* ret = t; t = nullptr; - return ret; - } -}; - -template <class Base, class T> -class TPointerBase: public TPointerCommon<Base, T> { -public: + return ret; + } +}; + +template <class Base, class T> +class TPointerBase: public TPointerCommon<Base, T> { +public: inline T& operator*() const noexcept { Y_ASSERT(this->AsT()); - - return *(this->AsT()); - } - + + return *(this->AsT()); + } + inline T& operator[](size_t n) const noexcept { Y_ASSERT(this->AsT()); - - return (this->AsT())[n]; - } -}; - -/* - * void*-like pointers does not have operator* - */ -template <class Base> -class TPointerBase<Base, void>: public TPointerCommon<Base, void> { -}; - + + return (this->AsT())[n]; + } +}; + +/* + * void*-like pointers does not have operator* + */ +template <class Base> +class TPointerBase<Base, void>: public TPointerCommon<Base, void> { +}; + template <class T, class D> -class TAutoPtr: public TPointerBase<TAutoPtr<T, D>, T> { -public: +class TAutoPtr: public TPointerBase<TAutoPtr<T, D>, T> { +public: inline TAutoPtr(T* t = nullptr) noexcept - : T_(t) - { - } - + : T_(t) + { + } + inline TAutoPtr(const TAutoPtr& t) noexcept - : T_(t.Release()) - { - } - + : T_(t.Release()) + { + } + inline ~TAutoPtr() { - DoDestroy(); - } - + DoDestroy(); + } + inline TAutoPtr& operator=(const TAutoPtr& t) noexcept { - if (this != &t) { - Reset(t.Release()); - } - - return *this; - } - + if (this != &t) { + Reset(t.Release()); + } + + return *this; + } + inline T* Release() const noexcept Y_WARN_UNUSED_RESULT { - return this->DoRelease(T_); - } - + return this->DoRelease(T_); + } + inline void Reset(T* t) noexcept { - if (T_ != t) { - DoDestroy(); - T_ = t; - } - } - + if (T_ != t) { + DoDestroy(); + T_ = t; + } + } + inline void Reset() noexcept { Destroy(); } inline void Destroy() noexcept { Reset(nullptr); - } - + } + inline void Swap(TAutoPtr& r) noexcept { - DoSwap(T_, r.T_); - } - + DoSwap(T_, r.T_); + } + inline T* Get() const noexcept { - return T_; - } - -#ifdef __cpp_impl_three_way_comparison + return T_; + } + +#ifdef __cpp_impl_three_way_comparison template <class Other> inline bool operator==(const Other& p) const noexcept { return (p == Get()); } -#endif -private: +#endif +private: inline void DoDestroy() noexcept { - if (T_) { - D::Destroy(T_); - } - } - -private: - mutable T* T_; -}; - + if (T_) { + D::Destroy(T_); + } + } + +private: + mutable T* T_; +}; + template <class T, class D> -class THolder: public TPointerBase<THolder<T, D>, T> { -public: +class THolder: public TPointerBase<THolder<T, D>, T> { +public: constexpr THolder() noexcept : T_(nullptr) { @@ -243,183 +243,183 @@ public: } explicit THolder(T* t) noexcept - : T_(t) - { - } - + : T_(t) + { + } + inline THolder(TAutoPtr<T, D> t) noexcept - : T_(t.Release()) - { - } - + : T_(t.Release()) + { + } + template <class U, class = TGuardConversion<T, U>> inline THolder(TAutoPtr<U, D> t) noexcept : T_(t.Release()) { } - inline THolder(THolder&& that) noexcept - : T_(that.Release()) - { - } + inline THolder(THolder&& that) noexcept + : T_(that.Release()) + { + } template <class U, class = TGuardConversion<T, U>> - inline THolder(THolder<U, D>&& that) noexcept - : T_(that.Release()) - { - } + inline THolder(THolder<U, D>&& that) noexcept + : T_(that.Release()) + { + } THolder(const THolder&) = delete; THolder& operator=(const THolder&) = delete; inline ~THolder() { - DoDestroy(); - } - + DoDestroy(); + } + inline void Destroy() noexcept { Reset(nullptr); - } - + } + inline T* Release() noexcept Y_WARN_UNUSED_RESULT { - return this->DoRelease(T_); - } - + return this->DoRelease(T_); + } + inline void Reset(T* t) noexcept { - if (T_ != t) { - DoDestroy(); - T_ = t; - } - } - + if (T_ != t) { + DoDestroy(); + T_ = t; + } + } + inline void Reset(TAutoPtr<T, D> t) noexcept { - Reset(t.Release()); - } + Reset(t.Release()); + } inline void Reset() noexcept { Destroy(); } inline void Swap(THolder& r) noexcept { - DoSwap(T_, r.T_); - } - + DoSwap(T_, r.T_); + } + inline T* Get() const noexcept { - return T_; - } - + return T_; + } + inline operator TAutoPtr<T, D>() noexcept { - return Release(); - } - + return Release(); + } + THolder& operator=(std::nullptr_t) noexcept { this->Reset(nullptr); return *this; } - THolder& operator=(THolder&& that) noexcept { - this->Reset(that.Release()); - return *this; - } + THolder& operator=(THolder&& that) noexcept { + this->Reset(that.Release()); + return *this; + } - template <class U> - THolder& operator=(THolder<U, D>&& that) noexcept { - this->Reset(that.Release()); - return *this; - } + template <class U> + THolder& operator=(THolder<U, D>&& that) noexcept { + this->Reset(that.Release()); + return *this; + } -#ifdef __cpp_impl_three_way_comparison +#ifdef __cpp_impl_three_way_comparison template <class Other> inline bool operator==(const Other& p) const noexcept { return (p == Get()); } -#endif -private: +#endif +private: inline void DoDestroy() noexcept { - if (T_) { - D::Destroy(T_); - } - } - -private: - T* T_; -}; - -template <typename T, typename... Args> + if (T_) { + D::Destroy(T_); + } + } + +private: + T* T_; +}; + +template <typename T, typename... Args> [[nodiscard]] THolder<T> MakeHolder(Args&&... args) { return THolder<T>(new T(std::forward<Args>(args)...)); } -/* - * usage: - * class T: public TRefCounted<T> - * and we get methods Ref() && UnRef() with - * proper destruction of last UnRef() - */ +/* + * usage: + * class T: public TRefCounted<T> + * and we get methods Ref() && UnRef() with + * proper destruction of last UnRef() + */ template <class T, class C, class D> -class TRefCounted { -public: +class TRefCounted { +public: inline TRefCounted(long initval = 0) noexcept - : Counter_(initval) - { - } - + : Counter_(initval) + { + } + inline ~TRefCounted() = default; - + inline void Ref(TAtomicBase d) noexcept { auto resultCount = Counter_.Add(d); Y_ASSERT(resultCount >= d); (void)resultCount; - } + } inline void Ref() noexcept { auto resultCount = Counter_.Inc(); Y_ASSERT(resultCount != 0); (void)resultCount; - } - + } + inline void UnRef(TAtomicBase d) noexcept { auto resultCount = Counter_.Sub(d); Y_ASSERT(resultCount >= 0); - if (resultCount == 0) { - D::Destroy(static_cast<T*>(this)); - } - } - + if (resultCount == 0) { + D::Destroy(static_cast<T*>(this)); + } + } + inline void UnRef() noexcept { - UnRef(1); - } + UnRef(1); + } inline TAtomicBase RefCount() const noexcept { - return Counter_.Val(); - } - + return Counter_.Val(); + } + inline void DecRef() noexcept { auto resultCount = Counter_.Dec(); Y_ASSERT(resultCount >= 0); (void)resultCount; - } + } - TRefCounted(const TRefCounted&) - : Counter_(0) - { - } + TRefCounted(const TRefCounted&) + : Counter_(0) + { + } - void operator=(const TRefCounted&) { - } + void operator=(const TRefCounted&) { + } + +private: + C Counter_; +}; -private: - C Counter_; -}; - /** * Atomically reference-counted base with a virtual destructor. * * @note Plays well with inheritance, should be used for refcounted base classes. */ -struct TThrRefBase: public TRefCounted<TThrRefBase, TAtomicCounter> { - virtual ~TThrRefBase(); -}; - +struct TThrRefBase: public TRefCounted<TThrRefBase, TAtomicCounter> { + virtual ~TThrRefBase(); +}; + /** * Atomically reference-counted base. * @@ -433,81 +433,81 @@ struct TThrRefBase: public TRefCounted<TThrRefBase, TAtomicCounter> { * @note To avoid accidental inheritance when it is not originally intended, * class @p T should be marked as final. */ -template <class T, class D = TDelete> -using TAtomicRefCount = TRefCounted<T, TAtomicCounter, D>; - +template <class T, class D = TDelete> +using TAtomicRefCount = TRefCounted<T, TAtomicCounter, D>; + /** * Non-atomically reference-counted base. * * @warning Not thread-safe. Use with great care. If in doubt, use @p ThrRefBase * or @p TAtomicRefCount instead. */ -template <class T, class D = TDelete> -using TSimpleRefCount = TRefCounted<T, TSimpleCounter, D>; - -template <class T> -class TDefaultIntrusivePtrOps { -public: +template <class T, class D = TDelete> +using TSimpleRefCount = TRefCounted<T, TSimpleCounter, D>; + +template <class T> +class TDefaultIntrusivePtrOps { +public: static inline void Ref(T* t) noexcept { Y_ASSERT(t); - - t->Ref(); - } - + + t->Ref(); + } + static inline void UnRef(T* t) noexcept { Y_ASSERT(t); - - t->UnRef(); - } + + t->UnRef(); + } static inline void DecRef(T* t) noexcept { Y_ASSERT(t); - t->DecRef(); - } - + t->DecRef(); + } + static inline long RefCount(const T* t) noexcept { Y_ASSERT(t); - - return t->RefCount(); - } -}; - + + return t->RefCount(); + } +}; + template <class T, class Ops> -class TIntrusivePtr: public TPointerBase<TIntrusivePtr<T, Ops>, T> { +class TIntrusivePtr: public TPointerBase<TIntrusivePtr<T, Ops>, T> { template <class U, class O> friend class TIntrusivePtr; - + template <class U, class O> friend class TIntrusiveConstPtr; -public: - struct TNoIncrement { - }; - +public: + struct TNoIncrement { + }; + inline TIntrusivePtr(T* t = nullptr) noexcept - : T_(t) - { - Ops(); - Ref(); - } - - inline TIntrusivePtr(T* t, TNoIncrement) noexcept - : T_(t) - { - Ops(); - } - + : T_(t) + { + Ops(); + Ref(); + } + + inline TIntrusivePtr(T* t, TNoIncrement) noexcept + : T_(t) + { + Ops(); + } + inline ~TIntrusivePtr() { UnRef(); - } - + } + inline TIntrusivePtr(const TIntrusivePtr& p) noexcept - : T_(p.T_) - { - Ref(); - } - + : T_(p.T_) + { + Ref(); + } + // NOTE: // without std::enable_if_t compiler sometimes tries to use this constructor inappropriately // e.g. @@ -531,18 +531,18 @@ public: p.T_ = nullptr; } - inline TIntrusivePtr(TIntrusivePtr&& p) noexcept - : T_(nullptr) - { - Swap(p); - } - + inline TIntrusivePtr(TIntrusivePtr&& p) noexcept + : T_(nullptr) + { + Swap(p); + } + inline TIntrusivePtr& operator=(TIntrusivePtr p) noexcept { - p.Swap(*this); - - return *this; - } - + p.Swap(*this); + + return *this; + } + // Effectively replace both: // Reset(const TIntrusivePtr&) // Reset(TIntrusivePtr&&) @@ -555,55 +555,55 @@ public: } inline T* Get() const noexcept { - return T_; - } - + return T_; + } + inline void Swap(TIntrusivePtr& r) noexcept { - DoSwap(T_, r.T_); - } - + DoSwap(T_, r.T_); + } + inline void Drop() noexcept { TIntrusivePtr(nullptr).Swap(*this); - } - + } + inline T* Release() const noexcept Y_WARN_UNUSED_RESULT { - T* res = T_; - if (T_) { - Ops::DecRef(T_); + T* res = T_; + if (T_) { + Ops::DecRef(T_); T_ = nullptr; } - return res; - } + return res; + } inline long RefCount() const noexcept { - return T_ ? Ops::RefCount(T_) : 0; - } - -#ifdef __cpp_impl_three_way_comparison + return T_ ? Ops::RefCount(T_) : 0; + } + +#ifdef __cpp_impl_three_way_comparison template <class Other> inline bool operator==(const Other& p) const noexcept { return (p == Get()); } -#endif -private: +#endif +private: inline void Ref() noexcept { - if (T_) { - Ops::Ref(T_); - } - } - + if (T_) { + Ops::Ref(T_); + } + } + inline void UnRef() noexcept { - if (T_) { - Ops::UnRef(T_); - } - } - -private: - mutable T* T_; -}; - + if (T_) { + Ops::UnRef(T_); + } + } + +private: + mutable T* T_; +}; + template <class T, class Ops> -struct THash<TIntrusivePtr<T, Ops>>: THash<const T*> { +struct THash<TIntrusivePtr<T, Ops>>: THash<const T*> { using THash<const T*>::operator(); inline size_t operator()(const TIntrusivePtr<T, Ops>& ptr) const { return THash<const T*>::operator()(ptr.Get()); @@ -613,35 +613,35 @@ struct THash<TIntrusivePtr<T, Ops>>: THash<const T*> { // Behaves like TIntrusivePtr but returns const T* to prevent user from accidentally modifying the referenced object. template <class T, class Ops> class TIntrusiveConstPtr: public TPointerBase<TIntrusiveConstPtr<T, Ops>, const T> { -public: +public: inline TIntrusiveConstPtr(T* t = nullptr) noexcept // we need a non-const pointer to Ref(), UnRef() and eventually delete it. - : T_(t) - { - Ops(); - Ref(); - } + : T_(t) + { + Ops(); + Ref(); + } inline ~TIntrusiveConstPtr() { - UnRef(); - } + UnRef(); + } inline TIntrusiveConstPtr(const TIntrusiveConstPtr& p) noexcept - : T_(p.T_) - { - Ref(); - } - - inline TIntrusiveConstPtr(TIntrusiveConstPtr&& p) noexcept - : T_(nullptr) - { - Swap(p); - } - + : T_(p.T_) + { + Ref(); + } + + inline TIntrusiveConstPtr(TIntrusiveConstPtr&& p) noexcept + : T_(nullptr) + { + Swap(p); + } + inline TIntrusiveConstPtr(TIntrusivePtr<T> p) noexcept : T_(p.T_) - { + { p.T_ = nullptr; - } + } template <class U, class = TGuardConversion<T, U>> inline TIntrusiveConstPtr(const TIntrusiveConstPtr<U>& p) noexcept @@ -658,10 +658,10 @@ public: } inline TIntrusiveConstPtr& operator=(TIntrusiveConstPtr p) noexcept { - p.Swap(*this); + p.Swap(*this); - return *this; - } + return *this; + } // Effectively replace both: // Reset(const TIntrusiveConstPtr&) @@ -675,49 +675,49 @@ public: } inline const T* Get() const noexcept { - return T_; - } + return T_; + } inline void Swap(TIntrusiveConstPtr& r) noexcept { - DoSwap(T_, r.T_); - } + DoSwap(T_, r.T_); + } inline void Drop() noexcept { TIntrusiveConstPtr(nullptr).Swap(*this); - } + } inline long RefCount() const noexcept { return T_ ? Ops::RefCount(T_) : 0; } -#ifdef __cpp_impl_three_way_comparison +#ifdef __cpp_impl_three_way_comparison template <class Other> inline bool operator==(const Other& p) const noexcept { return (p == Get()); } -#endif -private: +#endif +private: inline void Ref() noexcept { if (T_ != nullptr) { - Ops::Ref(T_); + Ops::Ref(T_); } - } + } inline void UnRef() noexcept { if (T_ != nullptr) { - Ops::UnRef(T_); + Ops::UnRef(T_); } - } + } -private: - T* T_; +private: + T* T_; template <class U, class O> friend class TIntrusiveConstPtr; }; -template <class T, class Ops> -struct THash<TIntrusiveConstPtr<T, Ops>>: THash<const T*> { +template <class T, class Ops> +struct THash<TIntrusiveConstPtr<T, Ops>>: THash<const T*> { using THash<const T*>::operator(); inline size_t operator()(const TIntrusiveConstPtr<T, Ops>& ptr) const { return THash<const T*>::operator()(ptr.Get()); @@ -725,59 +725,59 @@ struct THash<TIntrusiveConstPtr<T, Ops>>: THash<const T*> { }; template <class T, class Ops> -class TSimpleIntrusiveOps { - using TFunc = void (*)(T*) -#if __cplusplus >= 201703 - noexcept -#endif - ; - +class TSimpleIntrusiveOps { + using TFunc = void (*)(T*) +#if __cplusplus >= 201703 + noexcept +#endif + ; + static void DoRef(T* t) noexcept { - Ops::Ref(t); - } - + Ops::Ref(t); + } + static void DoUnRef(T* t) noexcept { - Ops::UnRef(t); - } - -public: + Ops::UnRef(t); + } + +public: inline TSimpleIntrusiveOps() noexcept { - InitStaticOps(); - } - + InitStaticOps(); + } + inline ~TSimpleIntrusiveOps() = default; - + static inline void Ref(T* t) noexcept { - Ref_(t); - } - + Ref_(t); + } + static inline void UnRef(T* t) noexcept { - UnRef_(t); - } - -private: + UnRef_(t); + } + +private: static inline void InitStaticOps() noexcept { - struct TInit { - inline TInit() noexcept { - Ref_ = DoRef; - UnRef_ = DoUnRef; - } - }; - - Singleton<TInit>(); - } - -private: - static TFunc Ref_; - static TFunc UnRef_; -}; - -template <class T, class Ops> + struct TInit { + inline TInit() noexcept { + Ref_ = DoRef; + UnRef_ = DoUnRef; + } + }; + + Singleton<TInit>(); + } + +private: + static TFunc Ref_; + static TFunc UnRef_; +}; + +template <class T, class Ops> typename TSimpleIntrusiveOps<T, Ops>::TFunc TSimpleIntrusiveOps<T, Ops>::Ref_ = nullptr; - -template <class T, class Ops> + +template <class T, class Ops> typename TSimpleIntrusiveOps<T, Ops>::TFunc TSimpleIntrusiveOps<T, Ops>::UnRef_ = nullptr; - + template <typename T, class Ops = TDefaultIntrusivePtrOps<T>, typename... Args> [[nodiscard]] TIntrusivePtr<T, Ops> MakeIntrusive(Args&&... args) { return new T{std::forward<Args>(args)...}; @@ -789,63 +789,63 @@ template <typename T, class Ops = TDefaultIntrusivePtrOps<T>, typename... Args> } template <class T, class C, class D> -class TSharedPtr: public TPointerBase<TSharedPtr<T, C, D>, T> { - template <class TT, class CC, class DD> - friend class TSharedPtr; +class TSharedPtr: public TPointerBase<TSharedPtr<T, C, D>, T> { + template <class TT, class CC, class DD> + friend class TSharedPtr; -public: +public: inline TSharedPtr() noexcept - : T_(nullptr) - , C_(nullptr) - { - } - - inline TSharedPtr(T* t) { - THolder<T, D> h(t); - - Init(h); - } - - inline TSharedPtr(TAutoPtr<T, D> t) { - Init(t); - } - + : T_(nullptr) + , C_(nullptr) + { + } + + inline TSharedPtr(T* t) { + THolder<T, D> h(t); + + Init(h); + } + + inline TSharedPtr(TAutoPtr<T, D> t) { + Init(t); + } + inline TSharedPtr(T* t, C* c) noexcept - : T_(t) - , C_(c) - { - } - + : T_(t) + , C_(c) + { + } + template <class TT, class = TGuardConversion<T, TT>> inline TSharedPtr(THolder<TT>&& t) { Init(t); } - inline ~TSharedPtr() { - UnRef(); - } - + inline ~TSharedPtr() { + UnRef(); + } + inline TSharedPtr(const TSharedPtr& t) noexcept - : T_(t.T_) - , C_(t.C_) - { - Ref(); - } - - inline TSharedPtr(TSharedPtr&& t) noexcept - : T_(nullptr) - , C_(nullptr) - { - Swap(t); - } - + : T_(t.T_) + , C_(t.C_) + { + Ref(); + } + + inline TSharedPtr(TSharedPtr&& t) noexcept + : T_(nullptr) + , C_(nullptr) + { + Swap(t); + } + template <class TT, class = TGuardConversion<T, TT>> inline TSharedPtr(const TSharedPtr<TT, C, D>& t) noexcept - : T_(t.T_) - , C_(t.C_) - { - Ref(); - } + : T_(t.T_) + , C_(t.C_) + { + Ref(); + } template <class TT, class = TGuardConversion<T, TT>> inline TSharedPtr(TSharedPtr<TT, C, D>&& t) noexcept @@ -857,83 +857,83 @@ public: } inline TSharedPtr& operator=(TSharedPtr t) noexcept { - t.Swap(*this); - - return *this; - } - + t.Swap(*this); + + return *this; + } + // Effectively replace both: // Reset(const TSharedPtr& t) // Reset(TSharedPtr&& t) inline void Reset(TSharedPtr t) noexcept { Swap(t); - } - + } + inline void Reset() noexcept { Drop(); } inline void Drop() noexcept { - TSharedPtr().Swap(*this); - } + TSharedPtr().Swap(*this); + } inline T* Get() const noexcept { - return T_; - } - + return T_; + } + inline C* ReferenceCounter() const noexcept { - return C_; - } - + return C_; + } + inline void Swap(TSharedPtr& r) noexcept { - DoSwap(T_, r.T_); - DoSwap(C_, r.C_); - } - + DoSwap(T_, r.T_); + DoSwap(C_, r.C_); + } + inline long RefCount() const noexcept { - return C_ ? C_->Val() : 0; - } - -#ifdef __cpp_impl_three_way_comparison + return C_ ? C_->Val() : 0; + } + +#ifdef __cpp_impl_three_way_comparison template <class Other> inline bool operator==(const Other& p) const noexcept { return (p == Get()); } -#endif -private: - template <class X> - inline void Init(X& t) { +#endif +private: + template <class X> + inline void Init(X& t) { C_ = !!t ? new C(1) : nullptr; - T_ = t.Release(); - } - + T_ = t.Release(); + } + inline void Ref() noexcept { - if (C_) { - C_->Inc(); - } - } - + if (C_) { + C_->Inc(); + } + } + inline void UnRef() noexcept { - if (C_ && !C_->Dec()) { - DoDestroy(); - } - } - + if (C_ && !C_->Dec()) { + DoDestroy(); + } + } + inline void DoDestroy() noexcept { - if (T_) { - D::Destroy(T_); - } - - delete C_; - } - -private: - T* T_; - C* C_; -}; - + if (T_) { + D::Destroy(T_); + } + + delete C_; + } + +private: + T* T_; + C* C_; +}; + template <class T, class C, class D> -struct THash<TSharedPtr<T, C, D>>: THash<const T*> { +struct THash<TSharedPtr<T, C, D>>: THash<const T*> { using THash<const T*>::operator(); inline size_t operator()(const TSharedPtr<T, C, D>& ptr) const { return THash<const T*>::operator()(ptr.Get()); @@ -942,85 +942,85 @@ struct THash<TSharedPtr<T, C, D>>: THash<const T*> { template <class T, class D = TDelete> using TAtomicSharedPtr = TSharedPtr<T, TAtomicCounter, D>; - -// use with great care. if in doubt, use TAtomicSharedPtr instead + +// use with great care. if in doubt, use TAtomicSharedPtr instead template <class T, class D = TDelete> using TSimpleSharedPtr = TSharedPtr<T, TSimpleCounter, D>; - -template <typename T, typename C, typename... Args> + +template <typename T, typename C, typename... Args> [[nodiscard]] TSharedPtr<T, C> MakeShared(Args&&... args) { return new T{std::forward<Args>(args)...}; } -template <typename T, typename... Args> +template <typename T, typename... Args> [[nodiscard]] inline TAtomicSharedPtr<T> MakeAtomicShared(Args&&... args) { return MakeShared<T, TAtomicCounter>(std::forward<Args>(args)...); } -template <typename T, typename... Args> +template <typename T, typename... Args> [[nodiscard]] inline TSimpleSharedPtr<T> MakeSimpleShared(Args&&... args) { return MakeShared<T, TSimpleCounter>(std::forward<Args>(args)...); } class TCopyClone { -public: - template <class T> - static inline T* Copy(T* t) { - if (t) - return t->Clone(); +public: + template <class T> + static inline T* Copy(T* t) { + if (t) + return t->Clone(); return nullptr; - } + } }; class TCopyNew { -public: - template <class T> - static inline T* Copy(T* t) { - if (t) - return new T(*t); +public: + template <class T> + static inline T* Copy(T* t) { + if (t) + return new T(*t); return nullptr; - } + } }; template <class T, class C, class D> class TCopyPtr: public TPointerBase<TCopyPtr<T, C, D>, T> { -public: +public: inline TCopyPtr(T* t = nullptr) noexcept - : T_(t) - { - } - - inline TCopyPtr(const TCopyPtr& t) - : T_(C::Copy(t.Get())) - { - } - - inline TCopyPtr(TCopyPtr&& t) noexcept - : T_(nullptr) - { - Swap(t); - } - + : T_(t) + { + } + + inline TCopyPtr(const TCopyPtr& t) + : T_(C::Copy(t.Get())) + { + } + + inline TCopyPtr(TCopyPtr&& t) noexcept + : T_(nullptr) + { + Swap(t); + } + inline ~TCopyPtr() { - DoDestroy(); - } + DoDestroy(); + } inline TCopyPtr& operator=(TCopyPtr t) noexcept { - t.Swap(*this); + t.Swap(*this); - return *this; - } + return *this; + } inline T* Release() noexcept Y_WARN_UNUSED_RESULT { - return DoRelease(T_); - } + return DoRelease(T_); + } inline void Reset(T* t) noexcept { - if (T_ != t) { - DoDestroy(); - T_ = t; + if (T_ != t) { + DoDestroy(); + T_ = t; } - } + } inline void Reset() noexcept { Destroy(); @@ -1028,37 +1028,37 @@ public: inline void Destroy() noexcept { Reset(nullptr); - } + } inline void Swap(TCopyPtr& r) noexcept { - DoSwap(T_, r.T_); - } + DoSwap(T_, r.T_); + } inline T* Get() const noexcept { - return T_; - } + return T_; + } -#ifdef __cpp_impl_three_way_comparison +#ifdef __cpp_impl_three_way_comparison template <class Other> inline bool operator==(const Other& p) const noexcept { return (p == Get()); } -#endif -private: +#endif +private: inline void DoDestroy() noexcept { - if (T_) - D::Destroy(T_); - } + if (T_) + D::Destroy(T_); + } -private: - T* T_; +private: + T* T_; }; // Copy-on-write pointer template <class TPtr, class TCopy> class TCowPtr: public TPointerBase<TCowPtr<TPtr, TCopy>, const typename TPtr::TValueType> { using T = typename TPtr::TValueType; - + public: inline TCowPtr() = default; @@ -1102,12 +1102,12 @@ public: T_.Reset(); } -#ifdef __cpp_impl_three_way_comparison +#ifdef __cpp_impl_three_way_comparison template <class Other> inline bool operator==(const Other& p) const noexcept { return (p == Get()); } -#endif +#endif private: inline void Unshare() { if (Shared()) { @@ -1120,16 +1120,16 @@ private: }; // saves .Get() on argument passing. Intended usage: Func(TPtrArg<X> p); ... TIntrusivePtr<X> p2; Func(p2); -template <class T> -class TPtrArg { - T* Ptr; - +template <class T> +class TPtrArg { + T* Ptr; + public: - TPtrArg(T* p) + TPtrArg(T* p) : Ptr(p) { } - TPtrArg(const TIntrusivePtr<T>& p) + TPtrArg(const TIntrusivePtr<T>& p) : Ptr(p.Get()) { } |