![]() |
User Manual, Developers Guide and API Documentation |
![]() |
00001 /******************************************************************************* 00002 * This file is part of openWNS (open Wireless Network Simulator) 00003 * _____________________________________________________________________________ 00004 * 00005 * Copyright (C) 2004-2007 00006 * Chair of Communication Networks (ComNets) 00007 * Kopernikusstr. 16, D-52074 Aachen, Germany 00008 * phone: ++49-241-80-27910, 00009 * fax: ++49-241-80-22242 00010 * email: info@openwns.org 00011 * www: http://www.openwns.org 00012 * _____________________________________________________________________________ 00013 * 00014 * openWNS is free software; you can redistribute it and/or modify it under the 00015 * terms of the GNU Lesser General Public License version 2 as published by the 00016 * Free Software Foundation; 00017 * 00018 * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY 00019 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00020 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00021 * details. 00022 * 00023 * You should have received a copy of the GNU Lesser General Public License 00024 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00025 * 00026 ******************************************************************************/ 00027 00028 #ifndef WNS_SMARTPTR_HPP 00029 #define WNS_SMARTPTR_HPP 00030 00031 #ifdef WNS_SMARTPTR_DEBUGGING 00032 #include <WNS/SmartPtrBase.hpp> 00033 #endif 00034 00035 #include <WNS/RefCountable.hpp> 00036 #include <WNS/TypeInfo.hpp> 00037 00038 #include <cassert> 00039 #include <cstdlib> 00040 #include <functional> 00041 #include <iostream> 00042 #include <list> 00043 00044 namespace wns { 00054 template <typename T> 00055 class SmartPtr 00056 #ifdef WNS_SMARTPTR_DEBUGGING 00057 : public SmartPtrBase 00058 #endif 00059 { 00060 // the underscores are for readability in error messages 00061 class YOU__SHOULD__NOT_COMPARE__THIS__WITH__ANYTHING__BUT__NULL 00062 { 00063 void operator delete(void*); 00064 }; 00065 00066 public: 00070 SmartPtr() : 00071 #ifdef WNS_SMARTPTR_DEBUGGING 00072 SmartPtrBase(), 00073 id(++getCounter()), 00074 file(), 00075 line(0), 00076 #endif 00077 ptr(NULL) 00078 { 00079 } 00080 00084 explicit 00085 SmartPtr(T* p) : 00086 #ifdef WNS_SMARTPTR_DEBUGGING 00087 SmartPtrBase(), 00088 id(++getCounter()), 00089 file(""), 00090 line(0), 00091 #endif 00092 ptr(p) 00093 { 00094 assert(ptr); 00095 ptr->incRefCount(); 00096 #ifdef WNS_SMARTPTR_DEBUGGING 00097 this->created(file, 0); 00098 #endif 00099 } 00100 00101 00105 SmartPtr(const SmartPtr& s) : 00106 #ifdef WNS_SMARTPTR_DEBUGGING 00107 SmartPtrBase(), 00108 id(++getCounter()), 00109 file(""), 00110 line(0), 00111 #endif 00112 ptr(s.ptr) 00113 { 00114 if(ptr) { 00115 ptr->incRefCount(); 00116 } 00117 #ifdef WNS_SMARTPTR_DEBUGGING 00118 this->created("", 0); 00119 #endif 00120 } 00121 00122 00126 template <typename OtherType> 00127 SmartPtr(const SmartPtr<OtherType>& s) : 00128 #ifdef WNS_SMARTPTR_DEBUGGING 00129 SmartPtrBase(), 00130 id(++getCounter()), 00131 file(""), 00132 line(0), 00133 #endif 00134 ptr(s.getPtr()) 00135 { 00136 if(ptr) { 00137 ptr->incRefCount(); 00138 } 00139 #ifdef WNS_SMARTPTR_DEBUGGING 00140 this->created("", 0); 00141 #endif 00142 } 00143 00144 #ifdef WNS_SMARTPTR_DEBUGGING 00145 00148 SmartPtr(const std::string& file, int line) : 00149 SmartPtrBase(), 00150 id(++getCounter()), 00151 file(""), 00152 line(0), 00153 ptr(NULL) 00154 { 00155 this->created(file, line); 00156 } 00157 00162 explicit 00163 SmartPtr(const std::string& file, int line, T* p) : 00164 SmartPtrBase(), 00165 id(++getCounter()), 00166 file(""), 00167 line(0), 00168 ptr(p) 00169 { 00170 assert(ptr); 00171 ptr->incRefCount(); 00172 this->created(file, line); 00173 } 00174 00179 SmartPtr(const std::string& file, int line, const SmartPtr& s) : 00180 SmartPtrBase(), 00181 id(++getCounter()), 00182 file(""), 00183 line(0), 00184 ptr(s.ptr) 00185 { 00186 if(ptr) { 00187 ptr->incRefCount(); 00188 } 00189 this->created(file, line); 00190 } 00191 00196 template <typename OtherType> 00197 SmartPtr(const std::string& file, int line, const SmartPtr<OtherType>& s) : 00198 SmartPtrBase(), 00199 id(++getCounter()), 00200 file(""), 00201 line(0), 00202 ptr(s.getPtr()) 00203 { 00204 if(ptr) { 00205 ptr->incRefCount(); 00206 } 00207 this->created(file, line); 00208 } 00209 #endif // defined WNS_SMARTPTR_DEBUGGING 00210 00214 SmartPtr& 00215 operator= (const SmartPtr& s) 00216 { 00217 if(ptr) { 00218 ptr->decRefCount(); 00219 } 00220 ptr=s.ptr; 00221 if(ptr) { 00222 ptr->incRefCount(); 00223 } 00224 return *this; 00225 } 00226 00230 template<typename OtherType> 00231 SmartPtr& 00232 operator= (const SmartPtr<OtherType>& s) 00233 { 00234 if(ptr) { 00235 ptr->decRefCount(); 00236 } 00237 ptr=s.getPtr(); 00238 if(ptr) { 00239 ptr->incRefCount(); 00240 } 00241 return *this; 00242 } 00243 00248 ~SmartPtr() 00249 { 00250 if(ptr) { 00251 ptr->decRefCount(); 00252 } 00253 #ifdef WNS_SMARTPTR_DEBUGGING 00254 this->deleted(); 00255 #endif 00256 } 00257 00261 T& 00262 operator* () const 00263 { 00264 assert(ptr != NULL); 00265 return *ptr; 00266 } 00267 00271 T* 00272 operator-> () const 00273 { 00274 assert(ptr != NULL); 00275 return ptr; 00276 } 00277 00283 operator YOU__SHOULD__NOT_COMPARE__THIS__WITH__ANYTHING__BUT__NULL* () const 00284 { 00285 if (ptr == NULL) 00286 { 00287 return NULL; 00288 } 00289 static YOU__SHOULD__NOT_COMPARE__THIS__WITH__ANYTHING__BUT__NULL foo; 00290 return &foo; 00291 } 00292 00296 template<typename OtherType> 00297 bool 00298 operator==(const SmartPtr<OtherType>& s) const 00299 { 00300 return ptr==s.getPtr(); 00301 } 00302 00306 template<typename OtherType> 00307 bool 00308 operator!=(const SmartPtr<OtherType>& s) const 00309 { 00310 return ptr!=s.getPtr(); 00311 } 00312 00316 template<typename OtherType> 00317 bool 00318 operator<(const SmartPtr<OtherType>& s) const 00319 { 00320 return ptr<s.getPtr(); 00321 } 00322 00326 template<typename OtherType> 00327 bool 00328 operator>(const SmartPtr<OtherType>& s) const 00329 { 00330 return ptr>s.getPtr(); 00331 } 00332 00336 template<typename OtherType> 00337 bool 00338 operator<=(const SmartPtr<OtherType>& s) const 00339 { 00340 return ptr<=s.getPtr(); 00341 } 00342 00346 template<typename OtherType> 00347 bool 00348 operator>=(const SmartPtr<OtherType>& s) const 00349 { 00350 return ptr>=s.getPtr(); 00351 } 00352 00356 T* 00357 getPtr() const 00358 { 00359 return ptr; 00360 } 00361 00367 long int 00368 getRefCount() 00369 { 00370 assert(ptr); 00371 return ptr->getRefCount(); 00372 } 00373 00377 static void 00378 printAllExistingPointers() 00379 { 00380 #ifdef WNS_SMARTPTR_DEBUGGING 00381 std::cout << "Currently existing SmartPtr<" 00382 << wns::TypeInfo::create<T>() 00383 << ">: " << "\n"; 00384 00385 for(typename std::list<SmartPtr*>::const_iterator itr = getAllPointers().begin(); 00386 itr != getAllPointers().end(); 00387 ++itr) { 00388 std::cout << "Pointer id: " << (*itr)->id << "\n" 00389 << "Created at: " << (*itr)->file << ":" << (*itr)->line << "\n" 00390 << "Backtrace: \n" << (*itr)->getBacktrace() << "\n"; 00391 00392 } 00393 #endif 00394 } 00395 00399 static void 00400 printNumberOfExistingPointers() 00401 { 00402 #ifdef WNS_SMARTPTR_DEBUGGING 00403 std::cout << "Number of currently existing SmartPtr<" 00404 << wns::TypeInfo::create<T>() 00405 << ">: " << getAllPointers().size() << "\n"; 00406 #endif 00407 } 00408 00409 00410 private: 00411 #ifdef WNS_SMARTPTR_DEBUGGING 00412 long long int id; 00413 00414 std::string file; 00415 int line; 00416 00417 void 00418 created(const std::string& _file, int _line) 00419 { 00420 this->getAllPointers().push_back(this); 00421 this->file = _file; 00422 this->line = _line; 00423 } 00424 00425 void 00426 deleted() 00427 { 00428 this->getAllPointers().remove(this); 00429 } 00430 00431 static long long int& 00432 getCounter() 00433 { 00434 static long long int counter = 0; 00435 return counter; 00436 } 00437 00438 static std::list<SmartPtr*>& 00439 getAllPointers() 00440 { 00441 static std::list<SmartPtr*> allPointers; 00442 return allPointers; 00443 } 00444 wns::TypeInfo 00445 getTypeInfo() const 00446 { 00447 return wns::TypeInfo::create<T>(); 00448 } 00449 00450 long long int 00451 getId() const 00452 { 00453 return id; 00454 } 00455 #endif // defined WNS_SMARTPTR_DEBUGGING 00456 00460 T* ptr; 00461 }; 00462 00463 template <typename T, typename P> 00464 T* 00465 dynamicCast(P* p) 00466 { 00467 return dynamic_cast<T*>(p); 00468 } 00469 00470 template <typename T, typename P> 00471 SmartPtr<T> 00472 dynamicCast(const SmartPtr<P>& p) 00473 { 00474 return SmartPtr<T>(dynamic_cast<T*>(p.getPtr())); 00475 } 00476 00477 template <typename T, typename P> 00478 T* 00479 staticCast(P* p) 00480 { 00481 return static_cast<T*>(p); 00482 } 00483 00484 template <typename T, typename P> 00485 SmartPtr<T> 00486 staticCast(const SmartPtr<P>& p) 00487 { 00488 return SmartPtr<T>(static_cast<T*>(p.getPtr())); 00489 } 00490 00495 template <class RETURNTYPE, class POINTERTYPE> 00496 class smart_ptr_mem_fun_t : 00497 public std::unary_function<SmartPtr<POINTERTYPE>, RETURNTYPE> 00498 { 00499 public: 00500 explicit 00501 smart_ptr_mem_fun_t(void (POINTERTYPE::*__pf)()) : 00502 _M_f(__pf) 00503 {} 00504 00505 RETURNTYPE 00506 operator()(SmartPtr<POINTERTYPE>& __p) const 00507 { 00508 (*__p.*_M_f)(); 00509 } 00510 00511 private: 00512 RETURNTYPE (POINTERTYPE::*_M_f)(); 00513 }; 00514 00515 template <class RETURNTYPE, class POINTERTYPE> 00516 class const_smart_ptr_mem_fun_t : 00517 public std::unary_function<SmartPtr<POINTERTYPE>, RETURNTYPE> 00518 { 00519 public: 00520 explicit 00521 const_smart_ptr_mem_fun_t(void (POINTERTYPE::*__pf)() const) : 00522 _M_f(__pf) 00523 {} 00524 00525 RETURNTYPE 00526 operator()(SmartPtr<POINTERTYPE>& __p) const 00527 { 00528 (*__p.*_M_f)(); 00529 } 00530 00531 private: 00532 RETURNTYPE (POINTERTYPE::*_M_f)() const; 00533 }; 00535 00544 template <class RETURNTYPE, class POINTERTYPE> 00545 inline smart_ptr_mem_fun_t<RETURNTYPE, POINTERTYPE> 00546 smart_ptr_mem_fun(RETURNTYPE (POINTERTYPE::*__f)()) 00547 { 00548 return smart_ptr_mem_fun_t<RETURNTYPE, POINTERTYPE>(__f); 00549 } 00550 00551 template <class RETURNTYPE, class POINTERTYPE> 00552 inline const_smart_ptr_mem_fun_t<RETURNTYPE, POINTERTYPE> 00553 smart_ptr_mem_fun(RETURNTYPE (POINTERTYPE::*__f)() const ) 00554 { 00555 return const_smart_ptr_mem_fun_t<RETURNTYPE, POINTERTYPE>(__f); 00556 } 00558 00559 } // wns 00560 00561 #endif // NOT defined WNS_SMARTPTR_HPP 00562 00563
1.5.5