shared_ptr.h

00001 /*
00002  * shared_ptr.h
00003  * This file is part of dbPager Classes Library (DCL)
00004  *
00005  * Copyright (c) 2008 Dennis Prochko <wolfsoft@mail.ru>
00006  *
00007  * DCL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation version 3.
00010  *
00011  * DCL is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with DCL; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor,
00019  * Boston, MA  02110-1301  USA
00020  */
00021 
00022 #ifndef _SHARED_PTR_H_
00023 #define _SHARED_PTR_H_
00024 
00025 namespace dbp {
00026 
00027 namespace local {
00028 
00029 template <class T>
00030 class smart_ptr {
00031 public:
00032         smart_ptr(): _data(new T), _refcount(0) { };
00033         smart_ptr(T *data): _data(data), _refcount(0) { };
00034         smart_ptr(const smart_ptr<T> &src):
00035           _data(new T(*(src._data))), _refcount(0) { };
00036         ~smart_ptr() {
00037                 delete _data;
00038         };
00039         smart_ptr<T>& operator=(const smart_ptr<T> &src) {
00040                 if (this == &src)
00041                         return *this;
00042                 delete _data;
00043                 _data = new T(*(src._data));
00044                 return *this;
00045         };
00046         T* operator->() const {
00047                 return _data;
00048         };
00049         T& operator*() const {
00050                 return *_data;
00051         };
00052         void invoke() { _refcount++; };
00053         void release() {
00054                 if (_refcount > 0)
00055                         _refcount--;
00056                 if (_refcount == 0) {
00057                         delete this;
00058                 };
00059         };
00060 private:
00061         T *_data;
00062         int _refcount;
00063 };
00064 
00065 } // namespace
00066 
00068 
00073 template <class T>
00074 class shared_ptr {
00075 public:
00077         shared_ptr(): _data(new local::smart_ptr<T>) {
00078                 _data->invoke();
00079         };
00081         shared_ptr(T *data): _data(new local::smart_ptr<T>(data)) {
00082                 _data->invoke();
00083         };
00085         shared_ptr(const shared_ptr<T> &src): _data(src._data) {
00086                 _data->invoke();
00087         };
00089         ~shared_ptr() {
00090                 _data->release();
00091         };
00093         shared_ptr<T>& operator=(const shared_ptr<T> &src) {
00094                 if ((this == &src) || (_data == src._data))
00095                         return *this;
00096                 _data->release();
00097                 _data = src._data;
00098                 _data->invoke();
00099                 return *this;
00100         };
00102         T* operator->() const {
00103                 return &(**_data);
00104         };
00106         T& operator*() const {
00107                 return *_data;
00108         };
00110         bool operator<(const shared_ptr<T> &src) const {
00111                 return _data < src._data;
00112         };
00113 private:
00114         local::smart_ptr<T> *_data;
00115 };
00116 
00117 }
00118 
00119 #endif /*_SHARED_PTR_H_*/
00120 

 
Support This Project
SourceForge.net Logo