/******************************************************************** created: 2008/05/27 created: 27:5:2008 10:03 filename: D:\Projects\ServiceSpace\ServiceSpace\ServiceSpaceLib\utilib\smart_ptr.h file path: D:\Projects\ServiceSpace\ServiceSpace\ServiceSpaceLib\utilib file base: smart_ptr file ext: h author: purpose: 提供用于资源管理的智能指针/弱指针实现 *********************************************************************/ #ifndef __UTILIB_SMART_PTR_H__ #define __UTILIB_SMART_PTR_H__ #include #include #include #include "pool_lock.h" #include "noncopyable.h" namespace utilib { class zero_ptr : public std::exception { typedef std::exception base; public: zero_ptr(){} const char * what()const throw() { return "zero pointer"; } }; // class zero_ptr namespace destroyer { template class freer { public: void operator()(T * p) { ::free(p); } static freer inst; private: freer() {} }; // class freer template freer freer::inst; template class deleter { public: void operator()(T * p) { delete p; } static deleter inst; private: deleter() {} }; // class deleter template deleter deleter::inst; template class arrary_deleter { public: void operator()(T * p) { delete []p; } static arrary_deleter inst; private: arrary_deleter() {} }; // class arrary_freer template arrary_deleter arrary_deleter::inst; template class noop { public: void operator()(T *) {} static noop inst; private: noop() {} }; // class done template noop noop::inst; template class deallocator_traits { public: template class deallocator { public: void operator()(typename Allocator::pointer p) { typedef typename Allocator::value_type value_type; p->~value_type(); Allocator().deallocate(p, 1); } static deallocator inst; }; }; // class deallocator_traits template template typename deallocator_traits::template deallocator deallocator_traits::deallocator ::inst; } // namespace destroyer namespace ownership { template class shared { public: shared() { count_ = 0; } template P clone(P & p) { pool_guard guard(lock_); ++count_; return p; } template bool release(P &) { assert(count_ < (unsigned)-1); pool_guard guard(lock_); return 0 == --count_; } private: pool_lock lock_; unsigned count_; }; // class shared template class auto_ { public: template P clone(P & p) { P t(p); p = P(); return t; } template bool release(P & p) { return p != P(); } }; } // namespace ownership namespace _internal { template class get_null_lock_inst { public: static null_lock inst; }; template null_lock get_null_lock_inst<_G>::inst; template class storage { public: storage(T * p, Destroyer & d, Synch & s) :pointer_(p), destroyer_(d), synch_(s) {} ~storage() { destroyer_(pointer_); } T * pointer_; Destroyer & destroyer_; Synch & synch_; Ownership ownership_; }; // class storage template class ret_pointer // : public noncopyable { public: ret_pointer(T * p, Synch & s) :pointer_(p), synch_(s) { synch_.lock(); } ~ret_pointer() { synch_.unlock(); } T * operator->()const { typedef T * p_type; assert(p_type() != pointer_); return pointer_; } private: T * pointer_; Synch & synch_; }; // class ret_pointer } // namespace _internal template class Destroyer, class Allocator, class Synch, template class Ownership, bool MTModel > class weak_ptr; template class Destroyer, class Allocator, class Synch, template class Ownership, bool MTModel > class smart_ptr_base { protected: typedef _internal::storage, Synch, Ownership > storage_type; typedef typename Allocator::template rebind::other storage_alloc; typedef Destroyer destroyer_type; typedef Ownership ownership_type; typedef Synch synch_type; typedef _internal::ret_pointer pointer; public: typedef T value_type; typedef T * pointer_type; typedef const T * const_pointer_type; typedef T & reference_type; typedef const T & const_reference_type; public: smart_ptr_base() : storage_(0) { } smart_ptr_base(T * p, synch_type & s, destroyer_type & d) : storage_(0) { if (p) { try { storage_alloc alloc; storage_ = (storage_type *)alloc.allocate(); if (!storage_) throw std::bad_alloc(); storage_ = new(storage_) storage_type(p, d, s); storage_ = storage_->ownership_.clone(storage_); } catch(...) { if (p) { d(p); } if (storage_) { storage_->pointer_ = 0; storage_->~storage_type(); storage_alloc().deallocate(storage_, 1); storage_ = 0; } throw; } // try-catch } // if (p) } smart_ptr_base(const smart_ptr_base & sp) : storage_(0) { if (sp.storage_) storage_ = sp.storage_->ownership_.clone(sp.storage_); } const smart_ptr_base & operator=(smart_ptr_base & sp) { reset(); if (sp.storage_) storage_ = sp.storage_->ownership_.clone(sp.storage_); return *this; } ~smart_ptr_base() { reset(); } void reset() { if (storage_) { if (storage_->ownership_.release(storage_)) { storage_->~storage_type(); storage_alloc().deallocate(storage_, 1); } storage_ = 0; } } pointer_type raw_ptr()const { return storage_ ? storage_->pointer_ : 0; } pointer operator->()const { if (storage_ && storage_->pointer_) return pointer(storage_->pointer_, storage_->synch_); throw zero_ptr(); } bool operator==(const smart_ptr_base & sp)const { if (storage_ == sp.storage_ && storage_ != 0) return storage_->pointer_ == sp.storage_->pointer_; return storage_ == 0 && sp.storage_ == 0; } bool operator==(const T * p)const { if (storage_) return storage_->pointer_ == p; return 0 == p; } bool operator!=(const smart_ptr_base & sp)const { return !this->operator==(sp); } bool operator!=(const T * p)const { return !this->operator==(p); } bool operator<(const smart_ptr_base & sp)const { if (storage_ == sp.storage_ && storage_ != 0) return storage_->pointer_ < sp.storage_->pointer_; return false; } bool operator<(const T * p)const { if (storage_) return storage_->pointer_ < p; return false; } bool operator<=(const smart_ptr_base & sp)const { return this->operator<(sp) || this->operator==(sp); } bool operator<=(const T * p)const { return this->operator<(p) || this->operator==(p); } bool operator>(const smart_ptr_base & sp)const { if (storage_ == sp.storage_ && storage_ != 0) return storage_->pointer_ > sp.storage_->pointer_; return false; } bool operator>(const T * p)const { if (storage_) return storage_->pointer_ > p; return false; } bool operator>=(const smart_ptr_base & sp)const { return this->operator>(sp) || this->operator==(sp); } bool operator>=(const T * p)const { return this->operator>(p) || this->operator==(p); } private: storage_type * storage_; public: template class Destroyer2, class Allocator2, class Synch2, template class Ownership2, bool MTModel2 > friend class weak_ptr; typedef weak_ptr weak_ptr_type; }; // class smart_ptr_base //} // namespace _internal template class Destroyer = destroyer::deleter, class Synch = null_lock, class Allocator = std::allocator, template class Ownership = ownership::shared, bool MTModel = true > class smart_ptr : public /*_internal::*/smart_ptr_base { typedef /*_internal::*/smart_ptr_base base; public: smart_ptr() { } smart_ptr(T * p, typename base::destroyer_type & d, typename base::synch_type & s) : base(p, s, d) { } typename base::pointer operator->()const { return base::operator->(); } }; // class smart_base template class Destroyer, class Allocator, template class Ownership, bool MTModel > class smart_ptr : public /*_internal::*/smart_ptr_base { typedef /*_internal::*/smart_ptr_base base; public: smart_ptr() { } smart_ptr(T * p, typename base::destroyer_type & d) : base(p, _internal::get_null_lock_inst<>::inst, d) { } typename base::pointer operator->()const { return base::operator->(); } }; template class Ownership, bool MTModel > class smart_ptr : public /*_internal::*/smart_ptr_base { typedef /*_internal::*/smart_ptr_base base; public: smart_ptr() { } smart_ptr(T * p, typename base::synch_type & s) : base(p, s, base::destroyer_type::inst) { } typename base::pointer operator->()const { return base::operator->(); } }; template class Ownership, bool MTModel > class smart_ptr : public /*_internal::*/smart_ptr_base { typedef /*_internal::*/smart_ptr_base base; public: smart_ptr() { } smart_ptr(T * p, typename base::synch_type & s) : base(p, s, base::destroyer_type::inst) { } typename base::pointer operator->()const { return base::operator->(); } }; template class Ownership, bool MTModel > class smart_ptr : public /*_internal::*/smart_ptr_base { typedef /*_internal::*/smart_ptr_base base; public: smart_ptr() { } smart_ptr(T * p, typename base::synch_type & s) : base(p, s, base::destroyer_type::inst) { } typename base::pointer operator->()const { return base::operator->(); } }; template class Ownership, bool MTModel > class smart_ptr : public /*_internal::*/smart_ptr_base { typedef /*_internal::*/smart_ptr_base base; public: smart_ptr() { } smart_ptr(T * p, typename base::synch_type & s) : base(p, s, base::destroyer_type::inst) { } typename base::pointer operator->()const { return base::operator->(); } }; template class Ownership, bool MTModel > class smart_ptr : public /*_internal::*/smart_ptr_base { typedef /*_internal::*/smart_ptr_base base; public: smart_ptr() { } smart_ptr(T * p) : base(p, _internal::get_null_lock_inst<>::inst, base::destroyer_type::inst) { } typename base::pointer operator->()const { return base::operator->(); } }; template class Ownership, bool MTModel > class smart_ptr : public /*_internal::*/smart_ptr_base { typedef /*_internal::*/smart_ptr_base base; public: smart_ptr() { } smart_ptr(T * p) : base(p, _internal::get_null_lock_inst<>::inst, base::destroyer_type::inst) { } typename base::pointer operator->()const { return base::operator->(); } }; template class Ownership, bool MTModel > class smart_ptr : public /*_internal::*/smart_ptr_base { typedef /*_internal::*/smart_ptr_base base; public: smart_ptr() { } smart_ptr(T * p) : base(p, _internal::get_null_lock_inst<>::inst, base::destroyer_type::inst) { } typename base::pointer operator->()const { return base::operator->(); } }; template class Ownership, bool MTModel > class smart_ptr : public /*_internal::*/smart_ptr_base { typedef /*_internal::*/smart_ptr_base base; public: smart_ptr() { } smart_ptr(T * p) : base(p, _internal::get_null_lock_inst<>::inst, base::destroyer_type::inst) { } typename base::pointer operator->()const { return base::operator->(); } }; template class Destroyer, class Synch, class Allocator, template class Ownership, bool MTModel > bool operator==(const smart_ptr & sp1, const smart_ptr & sp2) { return sp1.operator==(sp2); } template class Destroyer, class Synch, class Allocator, template class Ownership, bool MTModel > bool operator==(const smart_ptr & sp, const T * p) { return sp.operator==(p); } template class Destroyer, class Synch, class Allocator, template class Ownership, bool MTModel > bool operator==(const T * p, const smart_ptr & sp) { return sp.operator==(p); } template class Destroyer, class Synch, class Allocator, template class Ownership, bool MTModel > bool operator!=(const smart_ptr & sp1, const smart_ptr & sp2) { return sp1.operator!=(sp2); } template class Destroyer, class Synch, class Allocator, template class Ownership, bool MTModel > bool operator!=(const smart_ptr & sp1, const T * p2) { return sp1.operator!=(p2); } template class Destroyer, class Synch, class Allocator, template class Ownership, bool MTModel > bool operator!=(const T * p1, const smart_ptr & sp2) { return sp2.operator!=(p1); } template class Destroyer, class Synch, class Allocator, template class Ownership, bool MTModel > bool operator>(const smart_ptr & sp1, const smart_ptr & sp2) { return sp1.operator>(sp2); } template class Destroyer, class Synch, class Allocator, template class Ownership, bool MTModel > bool operator>(const smart_ptr & sp1, const T * p2) { return sp1.operator>(p2); } template class Destroyer, class Synch, class Allocator, template class Ownership, bool MTModel > bool operator>(const T * p1, const smart_ptr & sp2) { return sp2.operator<(p1); } template class Destroyer, class Synch, class Allocator, template class Ownership, bool MTModel > bool operator<(const smart_ptr & sp1, const smart_ptr & sp2) { return sp1.operator<(sp2); } template class Destroyer, class Synch, class Allocator, template class Ownership, bool MTModel > bool operator<(const smart_ptr & sp1, const T * p2) { return sp1.operator<(p2); } template class Destroyer, class Synch, class Allocator, template class Ownership, bool MTModel > bool operator<(const T * p1, const smart_ptr & sp2) { return sp2.operator>(p1); } template class Destroyer, class Synch, class Allocator, template class Ownership, bool MTModel > bool operator>=(const smart_ptr & sp1, const smart_ptr & sp2) { return sp1.operator>=(sp2); } template class Destroyer, class Synch, class Allocator, template class Ownership, bool MTModel > bool operator>=(const smart_ptr & sp1, const T * p2) { return sp1.operator>=(p2); } template class Destroyer, class Synch, class Allocator, template class Ownership, bool MTModel > bool operator>=(const T * p1, const smart_ptr & sp2) { return sp2.operator<=(p1); } template class Destroyer, class Synch, class Allocator, template class Ownership, bool MTModel > bool operator<=(const smart_ptr & sp1, const smart_ptr & sp2) { return sp1.operator<=(sp2); } template class Destroyer, class Synch, class Allocator, template class Ownership, bool MTModel > bool operator<=(const smart_ptr & sp1, const T * p2) { return sp1.operator<=(p2); } template class Destroyer, class Synch, class Allocator, template class Ownership, bool MTModel > bool operator<=(const T * p1, const smart_ptr & sp2) { return sp2.operator>=(p1); } template class Destroyer, class Allocator, class Synch, template class Ownership, bool MTModel > class weak_ptr { public: typedef smart_ptr smart_ptr_type; weak_ptr() : storage_(0) { } weak_ptr(const smart_ptr_type & sp) : storage_(sp.storage_) { } void operator=(const smart_ptr_type & sp) { storage_ = sp.storage_; } T * operator->() { return storage_ ? storage_->pointer_ : 0; } smart_ptr_type make_smart_ptr() { char tmp[sizeof(smart_ptr_type)]; smart_ptr_type * sp = reinterpret_cast(tmp); sp->storage_ = storage_; return *sp; } private: typename smart_ptr_type::storage_type * storage_; }; template class Destroyer, class Allocator, class Synch, template class Ownership, bool MTModel > weak_ptr make_weak_ptr( smart_ptr & sp) { return weak_ptr(sp); } } // namespace utilib #endif // header file