//===---------------------SharingPtr.h --------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef LLVM_ADT_SHARING_PTR #define LLVM_ADT_SHARING_PTR #include namespace llvm { namespace imp { class shared_count { shared_count(const shared_count&); shared_count& operator=(const shared_count&); protected: long shared_owners_; virtual ~shared_count(); private: virtual void on_zero_shared() = 0; public: explicit shared_count(long refs = 0) : shared_owners_(refs) {} void add_shared(); void release_shared(); long use_count() const {return shared_owners_ + 1;} }; template class shared_ptr_pointer : public shared_count { T data_; public: shared_ptr_pointer(T p) : data_(p) {} private: virtual void on_zero_shared(); }; template void shared_ptr_pointer::on_zero_shared() { delete data_; } } // namespace template class SharingPtr { public: typedef T element_type; private: element_type* ptr_; imp::shared_count* cntrl_; struct nat {int for_bool_;}; public: SharingPtr(); template explicit SharingPtr(Y* p); template SharingPtr(const SharingPtr& r, element_type *p); SharingPtr(const SharingPtr& r); template SharingPtr(const SharingPtr& r); ~SharingPtr(); SharingPtr& operator=(const SharingPtr& r); template SharingPtr& operator=(const SharingPtr& r); void swap(SharingPtr& r); void reset(); template void reset(Y* p); 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_ == 0;} operator nat*() const {return get() != 0;} private: template friend class SharingPtr; }; template inline SharingPtr::SharingPtr() : ptr_(0), cntrl_(0) { } template template SharingPtr::SharingPtr(Y* p) : ptr_(p) { std::auto_ptr hold(p); typedef imp::shared_ptr_pointer _CntrlBlk; cntrl_ = new _CntrlBlk(p); hold.release(); } template template inline SharingPtr::SharingPtr(const SharingPtr& r, element_type *p) : ptr_(p), cntrl_(r.cntrl_) { if (cntrl_) cntrl_->add_shared(); } template inline SharingPtr::SharingPtr(const SharingPtr& r) : ptr_(r.ptr_), cntrl_(r.cntrl_) { if (cntrl_) cntrl_->add_shared(); } template template inline SharingPtr::SharingPtr(const SharingPtr& r) : ptr_(r.ptr_), cntrl_(r.cntrl_) { if (cntrl_) cntrl_->add_shared(); } template SharingPtr::~SharingPtr() { if (cntrl_) cntrl_->release_shared(); } template inline SharingPtr& SharingPtr::operator=(const SharingPtr& r) { SharingPtr(r).swap(*this); return *this; } template template inline SharingPtr& SharingPtr::operator=(const SharingPtr& r) { SharingPtr(r).swap(*this); return *this; } template inline void SharingPtr::swap(SharingPtr& r) { std::swap(ptr_, r.ptr_); std::swap(cntrl_, r.cntrl_); } template inline void SharingPtr::reset() { SharingPtr().swap(*this); } template template inline void SharingPtr::reset(Y* p) { SharingPtr(p).swap(*this); } template inline bool operator==(const SharingPtr& __x, const SharingPtr& __y) { return __x.get() == __y.get(); } template inline bool operator!=(const SharingPtr& __x, const SharingPtr& __y) { return !(__x == __y); } template inline bool operator<(const SharingPtr& __x, const SharingPtr& __y) { return __x.get() < __y.get(); } template inline void swap(SharingPtr& __x, SharingPtr& __y) { __x.swap(__y); } template inline SharingPtr static_pointer_cast(const SharingPtr& r) { return SharingPtr(r, static_cast(r.get())); } template SharingPtr const_pointer_cast(const SharingPtr& r) { return SharingPtr(r, const_cast(r.get())); } } // namespace llvm #endif // LLVM_ADT_SHARING_PTR