CppDB
|
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