diff options
Diffstat (limited to 'lldb/include/lldb/Utility/SharingPtr.h')
| -rw-r--r-- | lldb/include/lldb/Utility/SharingPtr.h | 609 |
1 files changed, 0 insertions, 609 deletions
diff --git a/lldb/include/lldb/Utility/SharingPtr.h b/lldb/include/lldb/Utility/SharingPtr.h deleted file mode 100644 index e4ab3d27a69b..000000000000 --- a/lldb/include/lldb/Utility/SharingPtr.h +++ /dev/null @@ -1,609 +0,0 @@ -//===---------------------SharingPtr.h --------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef utility_SharingPtr_h_ -#define utility_SharingPtr_h_ - -#include <memory> - -// Microsoft Visual C++ currently does not enable std::atomic to work in CLR -// mode - as such we need to "hack around it" for MSVC++ builds only using -// Windows specific intrinsics instead of the C++11 atomic support -#ifdef _MSC_VER -#include <intrin.h> -#else -#include <atomic> -#endif - -#include <stddef.h> - - -//#define ENABLE_SP_LOGGING 1 // DON'T CHECK THIS LINE IN UNLESS COMMENTED OUT -#if defined(ENABLE_SP_LOGGING) - -extern "C" void track_sp(void *sp_this, void *ptr, long count); - -#endif - -namespace lldb_private { - -namespace imp { - -class shared_count { - shared_count(const shared_count &) = delete; - shared_count &operator=(const shared_count &) = delete; - -public: - explicit shared_count(long refs = 0) : shared_owners_(refs) {} - - void add_shared(); - void release_shared(); - long use_count() const { return shared_owners_ + 1; } - -protected: -#ifdef _MSC_VER - long shared_owners_; -#else - std::atomic<long> shared_owners_; -#endif - virtual ~shared_count(); - -private: - virtual void on_zero_shared() = 0; -}; - -template <class T> class shared_ptr_pointer : public shared_count { - T data_; - -public: - shared_ptr_pointer(T p) : data_(p) {} - -private: - void on_zero_shared() override; - - shared_ptr_pointer(const shared_ptr_pointer &) = delete; - shared_ptr_pointer &operator=(const shared_ptr_pointer &) = delete; -}; - -template <class T> void shared_ptr_pointer<T>::on_zero_shared() { - delete data_; -} - -template <class T> class shared_ptr_emplace : public shared_count { - T data_; - -public: - shared_ptr_emplace() : data_() {} - - template <class A0> shared_ptr_emplace(A0 &a0) : data_(a0) {} - - template <class A0, class A1> - shared_ptr_emplace(A0 &a0, A1 &a1) : data_(a0, a1) {} - - template <class A0, class A1, class A2> - shared_ptr_emplace(A0 &a0, A1 &a1, A2 &a2) : data_(a0, a1, a2) {} - - template <class A0, class A1, class A2, class A3> - shared_ptr_emplace(A0 &a0, A1 &a1, A2 &a2, A3 &a3) : data_(a0, a1, a2, a3) {} - - template <class A0, class A1, class A2, class A3, class A4> - shared_ptr_emplace(A0 &a0, A1 &a1, A2 &a2, A3 &a3, A4 &a4) - : data_(a0, a1, a2, a3, a4) {} - -private: - void on_zero_shared() override; - -public: - T *get() { return &data_; } -}; - -template <class T> void shared_ptr_emplace<T>::on_zero_shared() {} - -} // namespace imp - -template <class T> class SharingPtr { -public: - typedef T element_type; - -private: - element_type *ptr_; - imp::shared_count *cntrl_; - - struct nat { - int for_bool_; - }; - -public: - SharingPtr(); - SharingPtr(std::nullptr_t); - template <class Y> explicit SharingPtr(Y *p); - template <class Y> explicit SharingPtr(Y *p, imp::shared_count *ctrl_block); - template <class Y> SharingPtr(const SharingPtr<Y> &r, element_type *p); - SharingPtr(const SharingPtr &r); - template <class Y> SharingPtr(const SharingPtr<Y> &r); - - ~SharingPtr(); - - SharingPtr &operator=(const SharingPtr &r); - template <class Y> SharingPtr &operator=(const SharingPtr<Y> &r); - - void swap(SharingPtr &r); - void reset(); - template <class Y> void reset(Y *p); - void reset(std::nullptr_t); - - element_type *get() const { return ptr_; } - element_type &operator*() const { return *ptr_; } - element_type *operator->() const { return ptr_; } - long use_count() const { return cntrl_ ? cntrl_->use_count() : 0; } - bool unique() const { return use_count() == 1; } - bool empty() const { return cntrl_ == nullptr; } - operator nat *() const { return (nat *)get(); } - - static SharingPtr<T> make_shared(); - - template <class A0> static SharingPtr<T> make_shared(A0 &); - - template <class A0, class A1> static SharingPtr<T> make_shared(A0 &, A1 &); - - template <class A0, class A1, class A2> - static SharingPtr<T> make_shared(A0 &, A1 &, A2 &); - - template <class A0, class A1, class A2, class A3> - static SharingPtr<T> make_shared(A0 &, A1 &, A2 &, A3 &); - - template <class A0, class A1, class A2, class A3, class A4> - static SharingPtr<T> make_shared(A0 &, A1 &, A2 &, A3 &, A4 &); - -private: - template <class U> friend class SharingPtr; -}; - -template <class T> -inline SharingPtr<T>::SharingPtr() : ptr_(nullptr), cntrl_(nullptr) {} - -template <class T> -inline SharingPtr<T>::SharingPtr(std::nullptr_t) - : ptr_(nullptr), cntrl_(nullptr) {} - -template <class T> -template <class Y> -SharingPtr<T>::SharingPtr(Y *p) : ptr_(p), cntrl_(nullptr) { - std::unique_ptr<Y> hold(p); - typedef imp::shared_ptr_pointer<Y *> _CntrlBlk; - cntrl_ = new _CntrlBlk(p); - hold.release(); -} - -template <class T> -template <class Y> -SharingPtr<T>::SharingPtr(Y *p, imp::shared_count *cntrl_block) - : ptr_(p), cntrl_(cntrl_block) {} - -template <class T> -template <class Y> -inline SharingPtr<T>::SharingPtr(const SharingPtr<Y> &r, element_type *p) - : ptr_(p), cntrl_(r.cntrl_) { - if (cntrl_) - cntrl_->add_shared(); -} - -template <class T> -inline SharingPtr<T>::SharingPtr(const SharingPtr &r) - : ptr_(r.ptr_), cntrl_(r.cntrl_) { - if (cntrl_) - cntrl_->add_shared(); -} - -template <class T> -template <class Y> -inline SharingPtr<T>::SharingPtr(const SharingPtr<Y> &r) - : ptr_(r.ptr_), cntrl_(r.cntrl_) { - if (cntrl_) - cntrl_->add_shared(); -} - -template <class T> SharingPtr<T>::~SharingPtr() { - if (cntrl_) - cntrl_->release_shared(); -} - -template <class T> -inline SharingPtr<T> &SharingPtr<T>::operator=(const SharingPtr &r) { - SharingPtr(r).swap(*this); - return *this; -} - -template <class T> -template <class Y> -inline SharingPtr<T> &SharingPtr<T>::operator=(const SharingPtr<Y> &r) { - SharingPtr(r).swap(*this); - return *this; -} - -template <class T> inline void SharingPtr<T>::swap(SharingPtr &r) { - std::swap(ptr_, r.ptr_); - std::swap(cntrl_, r.cntrl_); -} - -template <class T> inline void SharingPtr<T>::reset() { - SharingPtr().swap(*this); -} - -template <class T> inline void SharingPtr<T>::reset(std::nullptr_t p) { - reset(); -} - -template <class T> template <class Y> inline void SharingPtr<T>::reset(Y *p) { - SharingPtr(p).swap(*this); -} - -template <class T> SharingPtr<T> SharingPtr<T>::make_shared() { - typedef imp::shared_ptr_emplace<T> CntrlBlk; - SharingPtr<T> r; - r.cntrl_ = new CntrlBlk(); - r.ptr_ = static_cast<CntrlBlk *>(r.cntrl_)->get(); - return r; -} - -template <class T> -template <class A0> -SharingPtr<T> SharingPtr<T>::make_shared(A0 &a0) { - typedef imp::shared_ptr_emplace<T> CntrlBlk; - SharingPtr<T> r; - r.cntrl_ = new CntrlBlk(a0); - r.ptr_ = static_cast<CntrlBlk *>(r.cntrl_)->get(); - return r; -} - -template <class T> -template <class A0, class A1> -SharingPtr<T> SharingPtr<T>::make_shared(A0 &a0, A1 &a1) { - typedef imp::shared_ptr_emplace<T> CntrlBlk; - SharingPtr<T> r; - r.cntrl_ = new CntrlBlk(a0, a1); - r.ptr_ = static_cast<CntrlBlk *>(r.cntrl_)->get(); - return r; -} - -template <class T> -template <class A0, class A1, class A2> -SharingPtr<T> SharingPtr<T>::make_shared(A0 &a0, A1 &a1, A2 &a2) { - typedef imp::shared_ptr_emplace<T> CntrlBlk; - SharingPtr<T> r; - r.cntrl_ = new CntrlBlk(a0, a1, a2); - r.ptr_ = static_cast<CntrlBlk *>(r.cntrl_)->get(); - return r; -} - -template <class T> -template <class A0, class A1, class A2, class A3> -SharingPtr<T> SharingPtr<T>::make_shared(A0 &a0, A1 &a1, A2 &a2, A3 &a3) { - typedef imp::shared_ptr_emplace<T> CntrlBlk; - SharingPtr<T> r; - r.cntrl_ = new CntrlBlk(a0, a1, a2, a3); - r.ptr_ = static_cast<CntrlBlk *>(r.cntrl_)->get(); - return r; -} - -template <class T> -template <class A0, class A1, class A2, class A3, class A4> -SharingPtr<T> SharingPtr<T>::make_shared(A0 &a0, A1 &a1, A2 &a2, A3 &a3, - A4 &a4) { - typedef imp::shared_ptr_emplace<T> CntrlBlk; - SharingPtr<T> r; - r.cntrl_ = new CntrlBlk(a0, a1, a2, a3, a4); - r.ptr_ = static_cast<CntrlBlk *>(r.cntrl_)->get(); - return r; -} - -template <class T> inline SharingPtr<T> make_shared() { - return SharingPtr<T>::make_shared(); -} - -template <class T, class A0> inline SharingPtr<T> make_shared(A0 &a0) { - return SharingPtr<T>::make_shared(a0); -} - -template <class T, class A0, class A1> -inline SharingPtr<T> make_shared(A0 &a0, A1 &a1) { - return SharingPtr<T>::make_shared(a0, a1); -} - -template <class T, class A0, class A1, class A2> -inline SharingPtr<T> make_shared(A0 &a0, A1 &a1, A2 &a2) { - return SharingPtr<T>::make_shared(a0, a1, a2); -} - -template <class T, class A0, class A1, class A2, class A3> -inline SharingPtr<T> make_shared(A0 &a0, A1 &a1, A2 &a2, A3 &a3) { - return SharingPtr<T>::make_shared(a0, a1, a2, a3); -} - -template <class T, class A0, class A1, class A2, class A3, class A4> -inline SharingPtr<T> make_shared(A0 &a0, A1 &a1, A2 &a2, A3 &a3, A4 &a4) { - return SharingPtr<T>::make_shared(a0, a1, a2, a3, a4); -} - -template <class T, class U> -inline bool operator==(const SharingPtr<T> &__x, const SharingPtr<U> &__y) { - return __x.get() == __y.get(); -} - -template <class T, class U> -inline bool operator!=(const SharingPtr<T> &__x, const SharingPtr<U> &__y) { - return !(__x == __y); -} - -template <class T, class U> -inline bool operator<(const SharingPtr<T> &__x, const SharingPtr<U> &__y) { - return __x.get() < __y.get(); -} - -template <class T> inline void swap(SharingPtr<T> &__x, SharingPtr<T> &__y) { - __x.swap(__y); -} - -template <class T, class U> -inline SharingPtr<T> static_pointer_cast(const SharingPtr<U> &r) { - return SharingPtr<T>(r, static_cast<T *>(r.get())); -} - -template <class T, class U> -SharingPtr<T> const_pointer_cast(const SharingPtr<U> &r) { - return SharingPtr<T>(r, const_cast<T *>(r.get())); -} - -template <class T> class LoggingSharingPtr : public SharingPtr<T> { - typedef SharingPtr<T> base; - -public: - typedef void (*Callback)(void *, const LoggingSharingPtr &, bool action); - // action: false means increment just happened - // true means decrement is about to happen - - LoggingSharingPtr() : cb_(0), baton_(nullptr) {} - - LoggingSharingPtr(Callback cb, void *baton) : cb_(cb), baton_(baton) { - if (cb_) - cb_(baton_, *this, false); - } - - template <class Y> - LoggingSharingPtr(Y *p) : base(p), cb_(0), baton_(nullptr) {} - - template <class Y> - LoggingSharingPtr(Y *p, Callback cb, void *baton) - : base(p), cb_(cb), baton_(baton) { - if (cb_) - cb_(baton_, *this, false); - } - - ~LoggingSharingPtr() { - if (cb_) - cb_(baton_, *this, true); - } - - LoggingSharingPtr(const LoggingSharingPtr &p) - : base(p), cb_(p.cb_), baton_(p.baton_) { - if (cb_) - cb_(baton_, *this, false); - } - - LoggingSharingPtr &operator=(const LoggingSharingPtr &p) { - if (cb_) - cb_(baton_, *this, true); - base::operator=(p); - cb_ = p.cb_; - baton_ = p.baton_; - if (cb_) - cb_(baton_, *this, false); - return *this; - } - - void reset() { - if (cb_) - cb_(baton_, *this, true); - base::reset(); - } - - template <class Y> void reset(Y *p) { - if (cb_) - cb_(baton_, *this, true); - base::reset(p); - if (cb_) - cb_(baton_, *this, false); - } - - void SetCallback(Callback cb, void *baton) { - cb_ = cb; - baton_ = baton; - } - - void ClearCallback() { - cb_ = 0; - baton_ = 0; - } - -private: - Callback cb_; - void *baton_; -}; - -template <class T> class IntrusiveSharingPtr; - -template <class T> class ReferenceCountedBase { -public: - explicit ReferenceCountedBase() : shared_owners_(-1) {} - - void add_shared(); - - void release_shared(); - - long use_count() const { return shared_owners_ + 1; } - -protected: - long shared_owners_; - - friend class IntrusiveSharingPtr<T>; - -private: - ReferenceCountedBase(const ReferenceCountedBase &) = delete; - ReferenceCountedBase &operator=(const ReferenceCountedBase &) = delete; -}; - -template <class T> void lldb_private::ReferenceCountedBase<T>::add_shared() { -#ifdef _MSC_VER - _InterlockedIncrement(&shared_owners_); -#else - ++shared_owners_; -#endif -} - -template <class T> -void lldb_private::ReferenceCountedBase<T>::release_shared() { -#ifdef _MSC_VER - if (_InterlockedDecrement(&shared_owners_) == -1) -#else - if (--shared_owners_ == -1) -#endif - delete static_cast<T *>(this); -} - -template <class T> -class ReferenceCountedBaseVirtual : public imp::shared_count { -public: - explicit ReferenceCountedBaseVirtual() : imp::shared_count(-1) {} - - ~ReferenceCountedBaseVirtual() override = default; - - void on_zero_shared() override; -}; - -template <class T> void ReferenceCountedBaseVirtual<T>::on_zero_shared() {} - -template <typename T> class IntrusiveSharingPtr { -public: - typedef T element_type; - - explicit IntrusiveSharingPtr() : ptr_(0) {} - - explicit IntrusiveSharingPtr(T *ptr) : ptr_(ptr) { add_shared(); } - - IntrusiveSharingPtr(const IntrusiveSharingPtr &rhs) : ptr_(rhs.ptr_) { - add_shared(); - } - - template <class X> - IntrusiveSharingPtr(const IntrusiveSharingPtr<X> &rhs) : ptr_(rhs.get()) { - add_shared(); - } - - IntrusiveSharingPtr &operator=(const IntrusiveSharingPtr &rhs) { - reset(rhs.get()); - return *this; - } - - template <class X> - IntrusiveSharingPtr &operator=(const IntrusiveSharingPtr<X> &rhs) { - reset(rhs.get()); - return *this; - } - - IntrusiveSharingPtr &operator=(T *ptr) { - reset(ptr); - return *this; - } - - ~IntrusiveSharingPtr() { - release_shared(); - ptr_ = nullptr; - } - - T &operator*() const { return *ptr_; } - - T *operator->() const { return ptr_; } - - T *get() const { return ptr_; } - - explicit operator bool() const { return ptr_ != 0; } - - void swap(IntrusiveSharingPtr &rhs) { - std::swap(ptr_, rhs.ptr_); -#if defined(ENABLE_SP_LOGGING) - track_sp(this, ptr_, use_count()); - track_sp(&rhs, rhs.ptr_, rhs.use_count()); -#endif - } - - void reset(T *ptr = nullptr) { IntrusiveSharingPtr(ptr).swap(*this); } - - long use_count() const { - if (ptr_) - return ptr_->use_count(); - return 0; - } - - bool unique() const { return use_count() == 1; } - -private: - element_type *ptr_; - - void add_shared() { - if (ptr_) { - ptr_->add_shared(); -#if defined(ENABLE_SP_LOGGING) - track_sp(this, ptr_, ptr_->use_count()); -#endif - } - } - void release_shared() { - if (ptr_) { -#if defined(ENABLE_SP_LOGGING) - track_sp(this, nullptr, ptr_->use_count() - 1); -#endif - ptr_->release_shared(); - } - } -}; - -template <class T, class U> -inline bool operator==(const IntrusiveSharingPtr<T> &lhs, - const IntrusiveSharingPtr<U> &rhs) { - return lhs.get() == rhs.get(); -} - -template <class T, class U> -inline bool operator!=(const IntrusiveSharingPtr<T> &lhs, - const IntrusiveSharingPtr<U> &rhs) { - return lhs.get() != rhs.get(); -} - -template <class T, class U> -inline bool operator==(const IntrusiveSharingPtr<T> &lhs, U *rhs) { - return lhs.get() == rhs; -} - -template <class T, class U> -inline bool operator!=(const IntrusiveSharingPtr<T> &lhs, U *rhs) { - return lhs.get() != rhs; -} - -template <class T, class U> -inline bool operator==(T *lhs, const IntrusiveSharingPtr<U> &rhs) { - return lhs == rhs.get(); -} - -template <class T, class U> -inline bool operator!=(T *lhs, const IntrusiveSharingPtr<U> &rhs) { - return lhs != rhs.get(); -} - -} // namespace lldb_private - -#endif // utility_SharingPtr_h_ |
