00001 // 00002 // Copyright (c) Benjamin Kaufmann 2010 00003 // 00004 // This is free software; you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation; either version 2 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // This file is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with this file; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 // 00018 // 00019 // NOTE: ProgramOptions is inspired by Boost.Program_options 00020 // see: www.boost.org/libs/program_options 00021 // 00022 #ifndef PROGRAM_OPTIONS_REFCOUNTABLE_H_INCLUDED 00023 #define PROGRAM_OPTIONS_REFCOUNTABLE_H_INCLUDED 00024 namespace ProgramOptions { namespace detail { 00025 00026 class RefCountable { 00027 public: 00028 RefCountable() : refCount_(1) {} 00029 int addRef() { return ++refCount_; } 00030 int release() { return --refCount_; } 00031 int refCount() const { return refCount_; } 00032 private: 00033 int refCount_; 00034 }; 00035 00036 template <class T> 00037 class IntrusiveSharedPtr { 00038 public: 00039 typedef T element_type; 00040 explicit IntrusiveSharedPtr(T* p = 0) throw() 00041 : ptr_(p) { /* NO add ref */ } 00042 IntrusiveSharedPtr(const IntrusiveSharedPtr& o) throw() 00043 : ptr_(o.ptr_) { addRef(); } 00044 ~IntrusiveSharedPtr() throw () { release(); } 00045 IntrusiveSharedPtr& operator=(const IntrusiveSharedPtr& other) { 00046 other.addRef(); 00047 this->release(); 00048 this->ptr_ = other.ptr_; 00049 return *this; 00050 } 00051 T& operator*() const throw() { return *ptr_; } 00052 T* operator->() const throw() { return ptr_; } 00053 T* get() const throw() { return ptr_; } 00054 void reset() throw() { release(); ptr_ = 0; } 00055 bool unique() const throw() { return !ptr_ || ptr_->refCount() == 1; } 00056 int count() const throw() { return ptr_ ? ptr_->refCount() : 0; } 00057 void swap(IntrusiveSharedPtr& b) { 00058 T* temp = ptr_; 00059 ptr_ = b.ptr_; 00060 b.ptr_ = temp; 00061 } 00062 private: 00063 T* ptr_; 00064 void addRef() const { if (ptr_) ptr_->addRef(); } 00065 void release() const { 00066 if (ptr_ && ptr_->release() == 0) { 00067 delete ptr_; 00068 } 00069 } 00070 }; 00071 00072 }} 00073 #endif