Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

acsComponentSmartPtr.h

Go to the documentation of this file.
00001 #ifndef ACSSMARTPOINTER_H 00002 #define ACSSMARTPOINTER_H 00003 /******************************************************************************* 00004 * ALMA - Atacama Large Millimiter Array 00005 * (c) National Research Council of Canada, 2007 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 * 00021 * "@(#) $Id: acsComponentSmartPtr.h,v 1.4.4.1 2008/12/08 22:48:27 agrimstrup Exp $" 00022 * 00023 * who when what 00024 * -------- -------- ---------------------------------------------- 00025 * arne 2007-10-09 created 00026 */ 00027 00028 /************************************************************************ 00029 * 00030 *---------------------------------------------------------------------- 00031 */ 00032 00033 /* The following piece of code alternates the linkage type to C for all 00034 functions declared within the braces, which is necessary to use the 00035 functions in C++-code. 00036 */ 00037 00038 #ifndef __cplusplus 00039 #error This is a C++ include file and cannot be used from plain C 00040 #endif 00041 00042 #include <logging.h> 00043 #include <lokiThreads.h> 00044 #include <lokiSmartPtr.h> 00045 #include <maciErrType.h> 00046 00047 namespace maci { 00048 00049 00056 template <class T, class H> 00057 class ComponentStorage 00058 { 00059 public: 00060 typedef T* StoredType; // the type of the pointee_ object 00061 typedef T* PointerType; // type returned by operator-> 00062 typedef T& ReferenceType; // type returned by operator* 00063 00067 ComponentStorage() : handle(0), sticky(true), pointee_(Default()) 00068 {} 00069 00073 ComponentStorage(const StoredType& p) : handle(0), sticky(true), pointee_(p) 00074 {} 00075 00076 // The storage policy doesn't initialize the stored pointer 00077 // which will be initialized by the OwnershipPolicy's Clone fn 00081 ComponentStorage(const ComponentStorage& rhs) : handle(rhs.handle), sticky(rhs.sticky), pointee_(0) 00082 {} 00083 00088 template <typename U, typename V> 00089 ComponentStorage(const ComponentStorage<U,V>&) : handle(0), sticky(true), pointee_(0) 00090 {} 00091 00101 void setValues(H *h, bool s, const StoredType& p) 00102 { 00103 handle = h; 00104 sticky = s; 00105 pointee_ = p; 00106 }; 00107 00111 PointerType operator->() const { return pointee_; } 00112 00116 ReferenceType operator*() const { return *pointee_; } 00117 00123 void Swap(ComponentStorage& rhs) 00124 { 00125 std::swap(pointee_, rhs.pointee_); 00126 std::swap(sticky, rhs.sticky); 00127 std::swap(handle, rhs.handle); 00128 } 00129 00130 // Accessors 00135 friend inline PointerType GetImpl(const ComponentStorage& sp) 00136 { return sp.pointee_; } 00137 00142 friend inline const StoredType& GetImplRef(const ComponentStorage& sp) 00143 { return sp.pointee_; } 00144 00149 friend inline StoredType& GetImplRef(ComponentStorage& sp) 00150 { return sp.pointee_; } 00151 00152 protected: 00153 00158 void Destroy() 00159 { 00160 try 00161 { 00162 if (handle && pointee_ && sticky) 00163 { 00164 handle->releaseComponent(pointee_->name()); 00165 } 00166 } 00167 catch(maciErrType::CannotReleaseComponentExImpl& ex) 00168 { 00169 ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ComponentStorage::Destroy", 00170 (LM_ERROR, "Unable to release component")); 00171 } 00172 catch(...) 00173 { 00174 ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ComponentStorage::Destroy", 00175 (LM_ERROR, "Unexpected exception caught when releasing component.")); 00176 } 00177 } 00178 // Default value to initialize the pointer 00179 static StoredType Default() 00180 { return 0; } 00181 00182 private: 00183 // Data 00184 H *handle; 00185 bool sticky; 00186 StoredType pointee_; 00187 }; 00188 00189 00190 class ContainerServices; 00191 00192 00193 /****************************************************************************** 00194 * The code below was taken from the lokiSmartPtr.h file, which is covered 00195 * by the license listed below. It has been modified to allow two parameter 00196 * StoragePolicy classes to be used. 00197 ******************************************************************************/ 00199 // The Loki Library 00200 // Copyright (c) 2001 by Andrei Alexandrescu 00201 // This code accompanies the book: 00202 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 00203 // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 00204 // Permission to use, copy, modify, distribute and sell this software for any 00205 // purpose is hereby granted without fee, provided that the above copyright 00206 // notice appear in all copies and that both that copyright notice and this 00207 // permission notice appear in supporting documentation. 00208 // The author or Addison-Wesley Longman make no representations about the 00209 // suitability of this software for any purpose. It is provided "as is" 00210 // without express or implied warranty. 00212 00213 template 00214 < 00215 typename T, 00216 typename H = ContainerServices, 00217 template <class> class OwnershipPolicy = Loki::RefCountedMTAdj<Loki::ObjectLevelLockable>::RefCountedMT, 00218 class ConversionPolicy = Loki::DisallowConversion, 00219 template <class> class CheckingPolicy = Loki::NoCheck, 00220 template <class,class> class StoragePolicy = ComponentStorage, 00221 template<class> class ConstnessPolicy = Loki::LOKI_DEFAULT_CONSTNESS 00222 > 00223 class SmartPtr 00224 : public StoragePolicy<T,H> 00225 , public OwnershipPolicy<typename StoragePolicy<T,H>::PointerType> 00226 , public CheckingPolicy<typename StoragePolicy<T,H>::StoredType> 00227 , public ConversionPolicy 00228 { 00229 typedef StoragePolicy<T,H> SP; 00230 typedef OwnershipPolicy<typename StoragePolicy<T,H>::PointerType> OP; 00231 typedef CheckingPolicy<typename StoragePolicy<T,H>::StoredType> KP; 00232 typedef ConversionPolicy CP; 00233 00234 public: 00235 typedef typename ConstnessPolicy<T>::Type* ConstPointerType; 00236 typedef typename ConstnessPolicy<T>::Type& ConstReferenceType; 00237 00238 typedef typename SP::PointerType PointerType; 00239 typedef typename SP::StoredType StoredType; 00240 typedef typename SP::ReferenceType ReferenceType; 00241 00242 typedef typename Loki::Select<OP::destructiveCopy,SmartPtr, const SmartPtr>::Result CopyArg; 00243 00244 private: 00245 struct NeverMatched; 00246 00247 #ifdef LOKI_SMARTPTR_CONVERSION_CONSTRUCTOR_POLICY 00248 typedef typename Loki::Select< CP::allow, const StoredType&, NeverMatched>::Result ImplicitArg; 00249 typedef typename Loki::Select<!CP::allow, const StoredType&, NeverMatched>::Result ExplicitArg; 00250 #else 00251 typedef const StoredType& ImplicitArg; 00252 typedef typename Loki::Select<false, const StoredType&, NeverMatched>::Result ExplicitArg; 00253 #endif 00254 00255 public: 00256 00257 SmartPtr() 00258 { KP::OnDefault(GetImpl(*this)); } 00259 00269 SmartPtr(H* h, bool s, T* p) 00270 { 00271 setValues(h, s, p); 00272 } 00273 00274 explicit 00275 SmartPtr(ExplicitArg p) : SP(p) 00276 { KP::OnInit(GetImpl(*this)); } 00277 00278 SmartPtr(ImplicitArg p) : SP(p) 00279 { KP::OnInit(GetImpl(*this)); } 00280 00281 SmartPtr(CopyArg& rhs) 00282 : SP(rhs), OP(rhs), KP(rhs), CP(rhs) 00283 { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); } 00284 00285 template 00286 < 00287 typename T1, 00288 typename H1, 00289 template <class> class OP1, 00290 class CP1, 00291 template <class> class KP1, 00292 template <class,class> class SP1, 00293 template <class> class CNP1 00294 > 00295 SmartPtr(const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs) 00296 : SP(rhs), OP(rhs), KP(rhs), CP(rhs) 00297 { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); } 00298 00299 template 00300 < 00301 typename T1, 00302 typename H1, 00303 template <class> class OP1, 00304 class CP1, 00305 template <class> class KP1, 00306 template <class,class> class SP1, 00307 template <class> class CNP1 00308 > 00309 SmartPtr(SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs) 00310 : SP(rhs), OP(rhs), KP(rhs), CP(rhs) 00311 { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); } 00312 00313 SmartPtr(Loki::RefToValue<SmartPtr> rhs) 00314 : SP(rhs), OP(rhs), KP(rhs), CP(rhs) 00315 {} 00316 00317 operator Loki::RefToValue<SmartPtr>() 00318 { return Loki::RefToValue<SmartPtr>(*this); } 00319 00320 SmartPtr& operator=(CopyArg& rhs) 00321 { 00322 SmartPtr temp(rhs); 00323 temp.Swap(*this); 00324 return *this; 00325 } 00326 00327 template 00328 < 00329 typename T1, 00330 typename H1, 00331 template <class> class OP1, 00332 class CP1, 00333 template <class> class KP1, 00334 template <class,class> class SP1, 00335 template <class> class CNP1 00336 > 00337 SmartPtr& operator=(const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs) 00338 { 00339 SmartPtr temp(rhs); 00340 temp.Swap(*this); 00341 return *this; 00342 } 00343 00344 template 00345 < 00346 typename T1, 00347 typename H1, 00348 template <class> class OP1, 00349 class CP1, 00350 template <class> class KP1, 00351 template <class,class> class SP1, 00352 template <class> class CNP1 00353 > 00354 SmartPtr& operator=(SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs) 00355 { 00356 SmartPtr temp(rhs); 00357 temp.Swap(*this); 00358 return *this; 00359 } 00360 00361 void Swap(SmartPtr& rhs) 00362 { 00363 OP::Swap(rhs); 00364 CP::Swap(rhs); 00365 KP::Swap(rhs); 00366 SP::Swap(rhs); 00367 } 00368 00369 ~SmartPtr() 00370 { 00371 if (OP::Release(GetImpl(*static_cast<SP*>(this)))) 00372 { 00373 SP::Destroy(); 00374 } 00375 } 00376 00377 friend inline void Release(SmartPtr& sp, typename SP::StoredType& p) 00378 { 00379 p = GetImplRef(sp); 00380 GetImplRef(sp) = SP::Default(); 00381 } 00382 00383 friend inline void Reset(SmartPtr& sp, typename SP::StoredType p) 00384 { SmartPtr(p).Swap(sp); } 00385 00386 template 00387 < 00388 typename T1, 00389 typename H1, 00390 template <class> class OP1, 00391 class CP1, 00392 template <class> class KP1, 00393 template <class,class> class SP1, 00394 template <class> class CNP1 00395 > 00396 bool Merge( SmartPtr< T1, H1, OP1, CP1, KP1, SP1, CNP1 > & rhs ) 00397 { 00398 if ( GetImpl( *this ) != GetImpl( rhs ) ) 00399 { 00400 return false; 00401 } 00402 return OP::Merge( rhs ); 00403 } 00404 00405 PointerType operator->() 00406 { 00407 KP::OnDereference(GetImplRef(*this)); 00408 return SP::operator->(); 00409 } 00410 00411 ConstPointerType operator->() const 00412 { 00413 KP::OnDereference(GetImplRef(*this)); 00414 return SP::operator->(); 00415 } 00416 00417 ReferenceType operator*() 00418 { 00419 KP::OnDereference(GetImplRef(*this)); 00420 return SP::operator*(); 00421 } 00422 00423 ConstReferenceType operator*() const 00424 { 00425 KP::OnDereference(GetImplRef(*this)); 00426 return SP::operator*(); 00427 } 00428 00429 bool operator!() const // Enables "if (!sp) ..." 00430 { return GetImpl(*this) == 0; } 00431 00432 static inline T * GetPointer( const SmartPtr & sp ) 00433 { return GetImpl( sp ); } 00434 00435 // Ambiguity buster 00436 template 00437 < 00438 typename T1, 00439 typename H1, 00440 template <class> class OP1, 00441 class CP1, 00442 template <class> class KP1, 00443 template <class,class> class SP1, 00444 template <class> class CNP1 00445 > 00446 bool operator==(const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const 00447 { return GetImpl(*this) == GetImpl(rhs); } 00448 00449 // Ambiguity buster 00450 template 00451 < 00452 typename T1, 00453 typename H1, 00454 template <class> class OP1, 00455 class CP1, 00456 template <class> class KP1, 00457 template <class,class> class SP1, 00458 template <class> class CNP1 00459 > 00460 bool operator!=(const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const 00461 { return !(*this == rhs); } 00462 00463 // Ambiguity buster 00464 template 00465 < 00466 typename T1, 00467 typename H1, 00468 template <class> class OP1, 00469 class CP1, 00470 template <class> class KP1, 00471 template <class,class> class SP1, 00472 template <class> class CNP1 00473 > 00474 bool operator<(const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const 00475 { return GetImpl(*this) < GetImpl(rhs); } 00476 00477 // Ambiguity buster 00478 template 00479 < 00480 typename T1, 00481 typename H1, 00482 template <class> class OP1, 00483 class CP1, 00484 template <class> class KP1, 00485 template <class,class> class SP1, 00486 template <class> class CNP1 00487 > 00488 inline bool operator > ( const SmartPtr< T1, H1, OP1, CP1, KP1, SP1, CNP1 > & rhs ) 00489 { 00490 return ( GetImpl( rhs ) < GetImpl( *this ) ); 00491 } 00492 00493 // Ambiguity buster 00494 template 00495 < 00496 typename T1, 00497 typename H1, 00498 template <class> class OP1, 00499 class CP1, 00500 template <class> class KP1, 00501 template <class,class> class SP1, 00502 template <class> class CNP1 00503 > 00504 inline bool operator <= ( const SmartPtr< T1, H1, OP1, CP1, KP1, SP1, CNP1 > & rhs ) 00505 { 00506 return !( GetImpl( rhs ) < GetImpl( *this ) ); 00507 } 00508 00509 // Ambiguity buster 00510 template 00511 < 00512 typename T1, 00513 typename H1, 00514 template <class> class OP1, 00515 class CP1, 00516 template <class> class KP1, 00517 template <class,class> class SP1, 00518 template <class> class CNP1 00519 > 00520 inline bool operator >= ( const SmartPtr< T1, H1, OP1, CP1, KP1, SP1, CNP1 > & rhs ) 00521 { 00522 return !( GetImpl( *this ) < GetImpl( rhs ) ); 00523 } 00524 00525 private: 00526 // Helper for enabling 'if (sp)' 00527 struct Tester 00528 { 00529 Tester(int) {} 00530 void dummy() {} 00531 }; 00532 00533 typedef void (Tester::*unspecified_boolean_type_)(); 00534 00535 typedef typename Loki::Select<CP::allow, Tester, unspecified_boolean_type_>::Result 00536 unspecified_boolean_type; 00537 00538 public: 00539 // enable 'if (sp)' 00540 operator unspecified_boolean_type() const 00541 { 00542 return !*this ? 0 : &Tester::dummy; 00543 } 00544 00545 private: 00546 // Helper for disallowing automatic conversion 00547 struct Insipid 00548 { 00549 Insipid(PointerType) {} 00550 }; 00551 00552 typedef typename Loki::Select<CP::allow, PointerType, Insipid>::Result 00553 AutomaticConversionResult; 00554 00555 public: 00556 operator AutomaticConversionResult() const 00557 { return GetImpl(*this); } 00558 }; 00559 00561 // free comparison operators for class template SmartPtr 00563 00568 00569 template 00570 < 00571 typename T, 00572 typename H, 00573 template <class> class OP, 00574 class CP, 00575 template <class> class KP, 00576 template <class,class> class SP, 00577 template <class> class CNP1, 00578 typename U 00579 > 00580 inline bool operator==(const SmartPtr<T, H, OP, CP, KP, SP, CNP1 >& lhs, 00581 U* rhs) 00582 { return GetImpl(lhs) == rhs; } 00583 00588 00589 template 00590 < 00591 typename T, 00592 typename H, 00593 template <class> class OP, 00594 class CP, 00595 template <class> class KP, 00596 template <class,class> class SP, 00597 template <class> class CNP1, 00598 typename U 00599 > 00600 inline bool operator==(U* lhs, 00601 const SmartPtr<T, H, OP, CP, KP, SP, CNP1 >& rhs) 00602 { return rhs == lhs; } 00603 00608 00609 template 00610 < 00611 typename T, 00612 typename H, 00613 template <class> class OP, 00614 class CP, 00615 template <class> class KP, 00616 template <class,class> class SP, 00617 template <class> class CNP, 00618 typename U 00619 > 00620 inline bool operator!=(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs, 00621 U* rhs) 00622 { return !(lhs == rhs); } 00623 00628 00629 template 00630 < 00631 typename T, 00632 typename H, 00633 template <class> class OP, 00634 class CP, 00635 template <class> class KP, 00636 template <class,class> class SP, 00637 template <class> class CNP, 00638 typename U 00639 > 00640 inline bool operator!=(U* lhs, 00641 const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs) 00642 { return rhs != lhs; } 00643 00648 00649 template 00650 < 00651 typename T, 00652 typename H, 00653 template <class> class OP, 00654 class CP, 00655 template <class> class KP, 00656 template <class,class> class SP, 00657 template <class> class CNP, 00658 typename U 00659 > 00660 inline bool operator<(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs, 00661 U* rhs) 00662 { 00663 return ( GetImpl( lhs ) < rhs ); 00664 } 00665 00670 00671 template 00672 < 00673 typename T, 00674 typename H, 00675 template <class> class OP, 00676 class CP, 00677 template <class> class KP, 00678 template <class,class> class SP, 00679 template <class> class CNP, 00680 typename U 00681 > 00682 inline bool operator<(U* lhs, 00683 const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs) 00684 { 00685 return ( GetImpl( rhs ) < lhs ); 00686 } 00687 00689 // operator> for lhs = SmartPtr, rhs = raw pointer 00692 00693 template 00694 < 00695 typename T, 00696 typename H, 00697 template <class> class OP, 00698 class CP, 00699 template <class> class KP, 00700 template <class,class> class SP, 00701 template <class> class CNP, 00702 typename U 00703 > 00704 inline bool operator>(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs, 00705 U* rhs) 00706 { return rhs < lhs; } 00707 00712 00713 template 00714 < 00715 typename T, 00716 typename H, 00717 template <class> class OP, 00718 class CP, 00719 template <class> class KP, 00720 template <class,class> class SP, 00721 template <class> class CNP, 00722 typename U 00723 > 00724 inline bool operator>(U* lhs, 00725 const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs) 00726 { return rhs < lhs; } 00727 00732 00733 template 00734 < 00735 typename T, 00736 typename H, 00737 template <class> class OP, 00738 class CP, 00739 template <class> class KP, 00740 template <class,class> class SP, 00741 template <class> class CNP, 00742 typename U 00743 > 00744 inline bool operator<=(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs, 00745 U* rhs) 00746 { return !(rhs < lhs); } 00747 00752 00753 template 00754 < 00755 typename T, 00756 typename H, 00757 template <class> class OP, 00758 class CP, 00759 template <class> class KP, 00760 template <class,class> class SP, 00761 template <class> class CNP, 00762 typename U 00763 > 00764 inline bool operator<=(U* lhs, 00765 const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs) 00766 { return !(rhs < lhs); } 00767 00772 00773 template 00774 < 00775 typename T, 00776 typename H, 00777 template <class> class OP, 00778 class CP, 00779 template <class> class KP, 00780 template <class,class> class SP, 00781 template <class> class CNP, 00782 typename U 00783 > 00784 inline bool operator>=(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs, 00785 U* rhs) 00786 { return !(lhs < rhs); } 00787 00792 00793 template 00794 < 00795 typename T, 00796 typename H, 00797 template <class> class OP, 00798 class CP, 00799 template <class> class KP, 00800 template <class,class> class SP, 00801 template <class> class CNP, 00802 typename U 00803 > 00804 inline bool operator>=(U* lhs, 00805 const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs) 00806 { return !(lhs < rhs); } 00807 00808 }; 00809 00814 00815 namespace std 00816 { 00817 template 00818 < 00819 typename T, 00820 typename H, 00821 template <class> class OP, 00822 class CP, 00823 template <class> class KP, 00824 template <class,class> class SP, 00825 template <class> class CNP 00826 > 00827 struct less< maci::SmartPtr<T, H, OP, CP, KP, SP, CNP > > 00828 : public binary_function<maci::SmartPtr<T, H, OP, CP, KP, SP, CNP >, 00829 maci::SmartPtr<T, H, OP, CP, KP, SP, CNP >, bool> 00830 { 00831 bool operator()(const maci::SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs, 00832 const maci::SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs) const 00833 { return less<T*>()(GetImpl(lhs), GetImpl(rhs)); } 00834 }; 00835 }; 00836 00837 #endif /* ACSSMARTPOINTER_H */

Generated on Thu Apr 30 02:30:48 2009 for ACS C++ API by doxygen 1.3.8