|
libpsynth 0.2.1
|
00001 00011 /* 00012 * Copyright (C) 2008, 2009 Juan Pedro BolĂvar Puente 00013 * 00014 * This file is part of Psychosynth. 00015 * 00016 * Psychosynth is free software: you can redistribute it and/or modify 00017 * it under the terms of the GNU General Public License as published by 00018 * the Free Software Foundation, either version 3 of the License, or 00019 * (at your option) any later version. 00020 * 00021 * Psychosynth is distributed in the hope that it will be useful, 00022 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00024 * GNU General Public License for more details. 00025 * 00026 * You should have received a copy of the GNU General Public License 00027 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00028 * 00029 */ 00030 00031 #ifndef PSYNTH_POINTER_HPP 00032 #define PSYNTH_POINTER_HPP 00033 00034 #include <memory> 00035 #include <algorithm> 00036 00037 namespace psynth 00038 { 00039 namespace base 00040 { 00041 00046 template <class PtrT> 00047 struct deleter 00048 { 00049 void operator () (PtrT ptr) 00050 { 00051 delete ptr; 00052 } 00053 }; 00054 00055 template <class T> 00056 class null_ptr 00057 { 00058 public: 00059 null_ptr () 00060 : m_ptr (0) 00061 {} 00062 00063 null_ptr (null_ptr& p) 00064 : m_ptr (p.m_ptr) 00065 {} 00066 00067 template <class Y> 00068 null_ptr (null_ptr<Y>& p) 00069 : m_ptr (p.m_ptr) 00070 {} 00071 00072 null_ptr (T* ptr) 00073 : m_ptr (ptr) 00074 {} 00075 00076 template <class Y> 00077 null_ptr (Y* ptr) 00078 : m_ptr (ptr) 00079 {} 00080 00081 T* operator-> () const 00082 { 00083 return m_ptr; 00084 } 00085 00086 T& operator* () const 00087 { 00088 return *m_ptr; 00089 } 00090 00091 operator T* () const 00092 { 00093 return m_ptr; 00094 } 00095 00096 operator bool () const 00097 { 00098 return m_ptr != 0; 00099 } 00100 00101 private: 00102 T* m_ptr; 00103 }; 00104 00105 template <class T> 00106 class mgr_ptr; 00107 00108 template <class T> 00109 class mgr_auto_ptr; 00110 00111 template <class T> 00112 class manage_me_ptr 00113 { 00114 template <class Y> friend class mgr_ptr; 00115 template <class Y> friend class mgr_auto_ptr; 00116 00117 T* m_ptr; 00118 public: 00119 00120 manage_me_ptr (T* p) 00121 : m_ptr (p) 00122 {} 00123 }; 00124 00125 template <class T> 00126 class mgr_ptr 00127 { 00128 T* m_ptr; 00129 bool m_managed; 00130 00131 public: 00132 ~mgr_ptr () { } 00133 00134 mgr_ptr () 00135 : m_ptr (0) 00136 , m_managed (false) {} 00137 00138 mgr_ptr (const mgr_ptr& p) 00139 : m_ptr (p.m_ptr) 00140 , m_managed (p.m_managed) 00141 {} 00142 00143 template <class Y> 00144 mgr_ptr (const mgr_ptr<Y>& p) 00145 : m_ptr (p.m_ptr) 00146 , m_managed (p.m_managed) 00147 {} 00148 00149 mgr_ptr (T* ptr) 00150 : m_ptr (ptr) 00151 , m_managed (false) 00152 {} 00153 00154 template <class Y> 00155 mgr_ptr (Y* ptr) 00156 : m_ptr (ptr) 00157 , m_managed (false) 00158 {} 00159 00160 template <class Y> 00161 mgr_ptr (const manage_me_ptr<Y>& p) 00162 : m_ptr (p.m_ptr) 00163 , m_managed (true) 00164 {} 00165 00166 mgr_ptr& operator= (const mgr_ptr& p) 00167 { 00168 m_ptr = p.m_ptr; 00169 m_managed = p.m_managed; 00170 return *this; 00171 } 00172 00173 template <class Y> 00174 mgr_ptr& operator= (const mgr_ptr<Y>& p) 00175 { 00176 m_ptr = p.m_ptr; 00177 m_managed = p.m_managed; 00178 return *this; 00179 } 00180 00181 mgr_ptr& operator= (T* p) 00182 { 00183 m_ptr = p; 00184 m_managed = false; 00185 return *this; 00186 } 00187 00188 template <class Y> 00189 mgr_ptr& operator= (Y* p) 00190 { 00191 m_ptr = p; 00192 m_managed = false; 00193 return *this; 00194 } 00195 00196 template <class Y> 00197 mgr_ptr& operator= (const manage_me_ptr<Y>& p) 00198 { 00199 m_ptr = p.m_ptr; 00200 m_managed = true; 00201 return *this; 00202 } 00203 00204 T* operator-> () const 00205 { 00206 return m_ptr; 00207 } 00208 00209 T& operator* () const 00210 { 00211 return *m_ptr; 00212 } 00213 00214 operator T* () const 00215 { 00216 return m_ptr; 00217 } 00218 00219 operator bool () const 00220 { 00221 return m_ptr != 0; 00222 } 00223 00224 T* get () const 00225 { 00226 return m_ptr; 00227 } 00228 00229 bool is_managed () const 00230 { 00231 return m_managed; 00232 } 00233 00234 void manage () 00235 { 00236 m_managed = true; 00237 } 00238 00239 void unmanage () 00240 { 00241 m_managed = false; 00242 } 00243 00244 void clean () 00245 { 00246 if (m_managed) { 00247 delete m_ptr; 00248 m_ptr = 0; 00249 } 00250 } 00251 }; 00252 00253 template <class T> 00254 class mgr_auto_ptr 00255 { 00256 T* m_ptr; 00257 bool m_managed; 00258 00259 public: 00260 ~mgr_auto_ptr () 00261 { 00262 clean (); 00263 } 00264 00265 mgr_auto_ptr () 00266 : m_ptr (0) 00267 , m_managed (false) 00268 {} 00269 00270 mgr_auto_ptr (mgr_auto_ptr& p) 00271 : m_ptr (p.m_ptr) 00272 , m_managed (p.m_managed) 00273 { 00274 p.unmanage (); 00275 } 00276 00277 template <class Y> 00278 mgr_auto_ptr (mgr_auto_ptr<Y>& p) 00279 : m_ptr (p.m_ptr) 00280 , m_managed (p.m_managed) 00281 { 00282 p.unmanage (); 00283 } 00284 00285 mgr_auto_ptr (T* ptr) 00286 : m_ptr (ptr) 00287 , m_managed (false) 00288 {} 00289 00290 template <class Y> 00291 mgr_auto_ptr (Y* ptr) 00292 : m_ptr (ptr) 00293 , m_managed (false) 00294 {} 00295 00296 template <class Y> 00297 mgr_auto_ptr (const manage_me_ptr<Y>& p) 00298 : m_ptr (p.m_ptr) 00299 , m_managed (true) 00300 {} 00301 00302 template <class Y> 00303 mgr_auto_ptr (std::auto_ptr<Y>& p) 00304 : m_ptr (p.release ()) 00305 , m_managed (true) 00306 {} 00307 00308 mgr_auto_ptr& operator= (mgr_auto_ptr& p) 00309 { 00310 if (&p != this) { 00311 clean (); 00312 m_ptr = p.m_ptr; 00313 m_managed = p.m_managed; 00314 p.unmanage (); 00315 } 00316 00317 return *this; 00318 } 00319 00320 template <class Y> 00321 mgr_auto_ptr& operator= (mgr_auto_ptr<Y>& p) 00322 { 00323 if (&p != this) { 00324 clean (); 00325 m_ptr = p.m_ptr; 00326 m_managed = p.m_managed; 00327 p.unmanage (); 00328 } 00329 return *this; 00330 } 00331 00332 mgr_auto_ptr& operator= (T* p) 00333 { 00334 if (p != m_ptr) { 00335 clean (); 00336 m_ptr = p; 00337 m_managed = false; 00338 } 00339 00340 return *this; 00341 } 00342 00343 template <class Y> 00344 mgr_auto_ptr& operator= (Y* p) 00345 { 00346 clean (); 00347 m_ptr = p; 00348 m_managed = false; 00349 return *this; 00350 } 00351 00352 template <class Y> 00353 mgr_auto_ptr& operator= (const manage_me_ptr<Y>& p) 00354 { 00355 clean (); 00356 m_ptr = p.m_ptr; 00357 m_managed = true; 00358 return *this; 00359 } 00360 00361 template <class Y> 00362 mgr_auto_ptr& operator= (std::auto_ptr<Y>& p) 00363 { 00364 clean (); 00365 m_ptr = p.release (); 00366 m_managed = true; 00367 return *this; 00368 } 00369 00370 T* operator-> () const 00371 { 00372 return m_ptr; 00373 } 00374 00375 T& operator* () const 00376 { 00377 return *m_ptr; 00378 } 00379 00380 operator T* () const 00381 { 00382 return m_ptr; 00383 } 00384 00385 operator bool () const 00386 { 00387 return m_ptr != 0; 00388 } 00389 00390 T* get () const 00391 { 00392 return m_ptr; 00393 } 00394 00395 bool is_managed () const 00396 { 00397 return m_managed; 00398 } 00399 00400 void manage () 00401 { 00402 m_managed = true; 00403 } 00404 00405 void unmanage () 00406 { 00407 m_managed = false; 00408 } 00409 00410 void clean () 00411 { 00412 if (m_managed) { 00413 delete m_ptr; 00414 m_ptr = 0; 00415 } 00416 } 00417 }; 00418 00419 template <class T> 00420 manage_me_ptr<T> manage (T* ptr) 00421 { 00422 return manage_me_ptr<T> (ptr); 00423 } 00424 00425 template <class T> 00426 class mgr_container : public T 00427 { 00428 public: 00429 ~mgr_container () 00430 { 00431 std::for_each (T::begin (), 00432 T::end (), 00433 std::mem_fun (&T::value_type::clean ())); 00434 } 00435 }; 00436 00437 template <class T> 00438 class mgr_assoc : public T 00439 { 00440 public: 00441 ~mgr_assoc () 00442 { 00443 for (typename T::iterator it = T::begin (); 00444 it != T::end (); 00445 ++it) 00446 it->second.clean (); 00447 } 00448 }; 00449 00450 } /* namespace base */ 00451 } /* namespace psynth*/ 00452 00453 namespace std 00454 { 00455 00456 template <typename T> 00457 struct remove_pointer<psynth::base::null_ptr<T>> 00458 { 00459 typedef T type; 00460 }; 00461 00462 } /* namespace std */ 00463 00464 #endif /* PSYNTH_POINTER_HPP */
1.7.4