CppDB
cppdb/ref_ptr.h
00001 
00002 //                                                                             
00003 //  Copyright (C) 2010-2011  Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>     
00004 //                                                                             
00005 //  Distributed under:
00006 //
00007 //                   the Boost Software License, Version 1.0.
00008 //              (See accompanying file LICENSE_1_0.txt or copy at 
00009 //                     http://www.boost.org/LICENSE_1_0.txt)
00010 //
00011 //  or (at your opinion) under:
00012 //
00013 //                               The MIT License
00014 //                 (See accompanying file MIT.txt or a copy at
00015 //              http://www.opensource.org/licenses/mit-license.php)
00016 //
00018 #ifndef CPPDB_REF_PTR_H
00019 #define CPPDB_REF_PTR_H
00020 #include <cppdb/errors.h>
00021 #include <cppdb/atomic_counter.h>
00022 
00023 namespace cppdb {
00036         template<typename T>
00037         class ref_ptr {
00038         public:
00042                 ref_ptr(T *v=0) : p(0)
00043                 {
00044                         reset(v);
00045                 }
00049                 ~ref_ptr()
00050                 {
00051                         reset();
00052                 }
00056                 ref_ptr(ref_ptr const &other) : p(0)
00057                 {
00058                         reset(other.p);
00059                 }
00063                 ref_ptr const &operator=(ref_ptr const &other)
00064                 {
00065                         reset(other.p);
00066                         return *this;
00067                 }
00068                 // Borland warns on assignments using operator=(ref_ptr...) with new sometype(...).
00069                 #ifdef __BORLANDC__
00070                 ref_ptr const &operator=(T *other)
00071                 {
00072                         reset(other);
00073                         return *this;
00074                 }
00075                 #endif
00076 
00077 
00078 
00079                 T *get() const
00080                 {
00081                         return p;
00082                 }
00086                 operator bool() const
00087                 {
00088                         return p!=0;
00089                 }
00093                 T *operator->() const
00094                 {
00095                         if(!p)
00096                                 throw cppdb_error("cppdb::ref_ptr: attempt to access an empty object");
00097                         return p;
00098                 }
00102                 T &operator*() const
00103                 {
00104                         if(!p)
00105                                 throw cppdb_error("cppdb::ref_ptr: attempt to access an empty object");
00106                         return *p;
00107                 }
00111                 void reset(T *v=0)
00112                 {
00113                         if(v==p)
00114                                 return;
00115                         if(p) {
00116                                 if(p->del_ref() == 0) {
00117                                         T::dispose(p);
00118                                 }
00119                                 p=0;
00120                         }
00121                         if(v) {
00122                                 v->add_ref();
00123                         }
00124                         p=v;
00125                 }
00126         private:
00127                 T *p;
00128         };
00129 
00133         class ref_counted {
00134         public:
00138                 ref_counted() : count_(0) 
00139                 {
00140                 }
00144                 virtual ~ref_counted()
00145                 {
00146                 }
00150                 long add_ref()
00151                 {
00152                         return ++count_;
00153                 }
00157                 long use_count() const
00158                 {
00159                         long val = count_;
00160                         return val;
00161                 }
00165                 long del_ref()
00166                 {
00167                         return --count_;
00168                 }
00172                 static void dispose(ref_counted *p)
00173                 {
00174                         delete p;
00175                 }
00176         private:
00177                 atomic_counter count_;
00178         };
00179 } // cppdb
00180 #endif
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator