00001 #ifndef ACSSMARTPOINTER_H
00002 #define ACSSMARTPOINTER_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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 #include <ACSErrTypeCommon.h>
00047
00048 namespace maci {
00049
00056 template <class T, class H>
00057 class ComponentStorage
00058 {
00059 public:
00060 typedef T* StoredType;
00061 typedef T* PointerType;
00062 typedef T& ReferenceType;
00063
00067 ComponentStorage() : handle(0), sticky(false), pointee_(Default())
00068 {}
00069
00073 ComponentStorage(const StoredType& p) : handle(0), sticky(false), pointee_(p)
00074 {}
00075
00076
00077
00081 ComponentStorage(const ComponentStorage& rhs) : handle(rhs.handle), sticky(rhs.sticky), pointee_(Default())
00082 {}
00083
00088 template <typename U, typename V>
00089 ComponentStorage(const ComponentStorage<U,V>&) : handle(0), sticky(false), pointee_(Default())
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
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
00156 bool inline isValid(const ComponentStorage& sp) const
00157 { return sp.isNil() || sp.handle != (H *)0; }
00158
00163 bool inline isNil() const
00164 { return CORBA::is_nil(pointee_);}
00165
00166
00167 protected:
00168
00173 void Destroy()
00174 {
00175 if (handle && pointee_ && sticky)
00176 {
00177 try
00178 {
00179 handle->releaseComponent(pointee_->name());
00180 }
00181 catch(maciErrType::CannotReleaseComponentExImpl& ex)
00182 {
00183 ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ComponentStorage::Destroy",
00184 (LM_ERROR, "Unable to release component"));
00185 }
00186 catch(...)
00187 {
00188 ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ComponentStorage::Destroy",
00189 (LM_ERROR, "Unexpected exception caught when releasing component."));
00190 }
00191 }
00192 }
00193
00194
00195
00196 static StoredType Default()
00197 { return T::_nil(); }
00198
00199 private:
00200
00201 H *handle;
00202 bool sticky;
00203 StoredType pointee_;
00204 };
00205
00206
00207 class ContainerServices;
00208
00209
00210
00211
00212
00213
00214
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00229
00230 template
00231 <
00232 typename T,
00233 typename H = ContainerServices,
00234 template <class> class OwnershipPolicy = Loki::RefCountedMTAdj<Loki::ObjectLevelLockable>::RefCountedMT,
00235 class ConversionPolicy = Loki::DisallowConversion,
00236 template <class> class CheckingPolicy = Loki::NoCheck,
00237 template <class,class> class StoragePolicy = ComponentStorage,
00238 template<class> class ConstnessPolicy = Loki::LOKI_DEFAULT_CONSTNESS
00239 >
00240 class SmartPtr
00241 : public StoragePolicy<T,H>
00242 , public OwnershipPolicy<typename StoragePolicy<T,H>::PointerType>
00243 , public CheckingPolicy<typename StoragePolicy<T,H>::StoredType>
00244 , public ConversionPolicy
00245 {
00246 typedef StoragePolicy<T,H> SP;
00247 typedef OwnershipPolicy<typename StoragePolicy<T,H>::PointerType> OP;
00248 typedef CheckingPolicy<typename StoragePolicy<T,H>::StoredType> KP;
00249 typedef ConversionPolicy CP;
00250
00251 public:
00252 typedef typename ConstnessPolicy<T>::Type* ConstPointerType;
00253 typedef typename ConstnessPolicy<T>::Type& ConstReferenceType;
00254
00255 typedef typename SP::PointerType PointerType;
00256 typedef typename SP::StoredType StoredType;
00257 typedef typename SP::ReferenceType ReferenceType;
00258
00259 typedef typename Loki::Select<OP::destructiveCopy,SmartPtr, const SmartPtr>::Result CopyArg;
00260
00261 private:
00262 struct NeverMatched;
00263
00264 #ifdef LOKI_SMARTPTR_CONVERSION_CONSTRUCTOR_POLICY
00265 typedef typename Loki::Select< CP::allow, const StoredType&, NeverMatched>::Result ImplicitArg;
00266 typedef typename Loki::Select<!CP::allow, const StoredType&, NeverMatched>::Result ExplicitArg;
00267 #else
00268 typedef const StoredType& ImplicitArg;
00269 typedef typename Loki::Select<false, const StoredType&, NeverMatched>::Result ExplicitArg;
00270 #endif
00271
00272 public:
00273
00274 SmartPtr()
00275 { KP::OnDefault(GetImpl(*this)); }
00276
00284 SmartPtr(H* h, bool s, T* p)
00285 {
00286 setValues(h, s, p);
00287 }
00288
00289 SmartPtr(CopyArg& rhs)
00290 : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
00291 { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
00292
00293 template
00294 <
00295 typename T1,
00296 typename H1,
00297 template <class> class OP1,
00298 class CP1,
00299 template <class> class KP1,
00300 template <class,class> class SP1,
00301 template <class> class CNP1
00302 >
00303 SmartPtr(const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
00304 : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
00305 { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
00306
00307 template
00308 <
00309 typename T1,
00310 typename H1,
00311 template <class> class OP1,
00312 class CP1,
00313 template <class> class KP1,
00314 template <class,class> class SP1,
00315 template <class> class CNP1
00316 >
00317 SmartPtr(SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
00318 : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
00319 { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
00320
00321 SmartPtr(Loki::RefToValue<SmartPtr> rhs)
00322 : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
00323 {}
00324
00325 operator Loki::RefToValue<SmartPtr>()
00326 { return Loki::RefToValue<SmartPtr>(*this); }
00327
00328 SmartPtr& operator=(CopyArg& rhs)
00329 {
00330 SmartPtr temp(rhs);
00331 if (!isValid(rhs))
00332 throw ACSErrTypeCommon::IllegalArgumentExImpl(__FILE__, __LINE__, "SmartPtr::operator=");
00333 else
00334 temp.Swap(*this);
00335 return *this;
00336 }
00337
00338 template
00339 <
00340 typename T1,
00341 typename H1,
00342 template <class> class OP1,
00343 class CP1,
00344 template <class> class KP1,
00345 template <class,class> class SP1,
00346 template <class> class CNP1
00347 >
00348 SmartPtr& operator=(const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
00349 {
00350 SmartPtr temp(rhs);
00351 if (!isValid(rhs))
00352 throw ACSErrTypeCommon::IllegalArgumentExImpl(__FILE__, __LINE__, "SmartPtr::operator=");
00353 else
00354 temp.Swap(*this);
00355 return *this;
00356 }
00357
00358 template
00359 <
00360 typename T1,
00361 typename H1,
00362 template <class> class OP1,
00363 class CP1,
00364 template <class> class KP1,
00365 template <class,class> class SP1,
00366 template <class> class CNP1
00367 >
00368 SmartPtr& operator=(SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
00369 {
00370 SmartPtr temp(rhs);
00371 if (!isValid(rhs))
00372 throw ACSErrTypeCommon::IllegalArgumentExImpl(__FILE__, __LINE__, "SmartPtr::operator=");
00373 else
00374 temp.Swap(*this);
00375 return *this;
00376 }
00377
00378 void Swap(SmartPtr& rhs)
00379 {
00380 OP::Swap(rhs);
00381 CP::Swap(rhs);
00382 KP::Swap(rhs);
00383 SP::Swap(rhs);
00384 }
00385
00386 ~SmartPtr()
00387 {
00388 if (!SP::isNil() && OP::Release(GetImpl(*static_cast<SP*>(this))))
00389 {
00390 SP::Destroy();
00391 }
00392 }
00393
00394 void release()
00395 {
00396 OP temp;
00397 this->~SmartPtr();
00398 this->setValues((H *)0, false, SP::Default());
00399 OP::Swap(temp);
00400 }
00401
00402 template
00403 <
00404 typename T1,
00405 typename H1,
00406 template <class> class OP1,
00407 class CP1,
00408 template <class> class KP1,
00409 template <class,class> class SP1,
00410 template <class> class CNP1
00411 >
00412 bool Merge( SmartPtr< T1, H1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
00413 {
00414 if ( GetImpl( *this ) != GetImpl( rhs ) )
00415 {
00416 return false;
00417 }
00418 return OP::Merge( rhs );
00419 }
00420
00421 PointerType operator->()
00422 {
00423 KP::OnDereference(GetImplRef(*this));
00424 return SP::operator->();
00425 }
00426
00427 ConstPointerType operator->() const
00428 {
00429 KP::OnDereference(GetImplRef(*this));
00430 return SP::operator->();
00431 }
00432
00433 ReferenceType operator*()
00434 {
00435 KP::OnDereference(GetImplRef(*this));
00436 return SP::operator*();
00437 }
00438
00439 ConstReferenceType operator*() const
00440 {
00441 KP::OnDereference(GetImplRef(*this));
00442 return SP::operator*();
00443 }
00444
00445 bool operator!() const
00446 { return GetImpl(*this) == 0; }
00447
00448 static inline T * GetPointer( const SmartPtr & sp )
00449 { return GetImpl( sp ); }
00450
00451
00452 template
00453 <
00454 typename T1,
00455 typename H1,
00456 template <class> class OP1,
00457 class CP1,
00458 template <class> class KP1,
00459 template <class,class> class SP1,
00460 template <class> class CNP1
00461 >
00462 bool operator==(const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const
00463 { return GetImpl(*this) == GetImpl(rhs); }
00464
00465
00466 template
00467 <
00468 typename T1,
00469 typename H1,
00470 template <class> class OP1,
00471 class CP1,
00472 template <class> class KP1,
00473 template <class,class> class SP1,
00474 template <class> class CNP1
00475 >
00476 bool operator!=(const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const
00477 { return !(*this == rhs); }
00478
00479
00480 template
00481 <
00482 typename T1,
00483 typename H1,
00484 template <class> class OP1,
00485 class CP1,
00486 template <class> class KP1,
00487 template <class,class> class SP1,
00488 template <class> class CNP1
00489 >
00490 bool operator<(const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const
00491 { return GetImpl(*this) < GetImpl(rhs); }
00492
00493
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
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( rhs ) < GetImpl( *this ) );
00523 }
00524
00525
00526 template
00527 <
00528 typename T1,
00529 typename H1,
00530 template <class> class OP1,
00531 class CP1,
00532 template <class> class KP1,
00533 template <class,class> class SP1,
00534 template <class> class CNP1
00535 >
00536 inline bool operator >= ( const SmartPtr< T1, H1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
00537 {
00538 return !( GetImpl( *this ) < GetImpl( rhs ) );
00539 }
00540
00541 private:
00542
00543 struct Tester
00544 {
00545 Tester(int) {}
00546 void dummy() {}
00547 };
00548
00549 typedef void (Tester::*unspecified_boolean_type_)();
00550
00551 typedef typename Loki::Select<CP::allow, Tester, unspecified_boolean_type_>::Result
00552 unspecified_boolean_type;
00553
00554 public:
00555
00556 operator unspecified_boolean_type() const
00557 {
00558 return !*this ? 0 : &Tester::dummy;
00559 }
00560
00561 private:
00562
00563 struct Insipid
00564 {
00565 Insipid(PointerType) {}
00566 };
00567
00568 typedef typename Loki::Select<CP::allow, PointerType, Insipid>::Result
00569 AutomaticConversionResult;
00570
00571 public:
00572 operator AutomaticConversionResult() const
00573 { return GetImpl(*this); }
00574 };
00575
00577
00579
00584
00585 template
00586 <
00587 typename T,
00588 typename H,
00589 template <class> class OP,
00590 class CP,
00591 template <class> class KP,
00592 template <class,class> class SP,
00593 template <class> class CNP1,
00594 typename U
00595 >
00596 inline bool operator==(const SmartPtr<T, H, OP, CP, KP, SP, CNP1 >& lhs,
00597 U* rhs)
00598 { return GetImpl(lhs) == rhs; }
00599
00604
00605 template
00606 <
00607 typename T,
00608 typename H,
00609 template <class> class OP,
00610 class CP,
00611 template <class> class KP,
00612 template <class,class> class SP,
00613 template <class> class CNP1,
00614 typename U
00615 >
00616 inline bool operator==(U* lhs,
00617 const SmartPtr<T, H, OP, CP, KP, SP, CNP1 >& rhs)
00618 { return rhs == lhs; }
00619
00624
00625 template
00626 <
00627 typename T,
00628 typename H,
00629 template <class> class OP,
00630 class CP,
00631 template <class> class KP,
00632 template <class,class> class SP,
00633 template <class> class CNP,
00634 typename U
00635 >
00636 inline bool operator!=(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00637 U* rhs)
00638 { return !(lhs == rhs); }
00639
00644
00645 template
00646 <
00647 typename T,
00648 typename H,
00649 template <class> class OP,
00650 class CP,
00651 template <class> class KP,
00652 template <class,class> class SP,
00653 template <class> class CNP,
00654 typename U
00655 >
00656 inline bool operator!=(U* lhs,
00657 const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
00658 { return rhs != lhs; }
00659
00664
00665 template
00666 <
00667 typename T,
00668 typename H,
00669 template <class> class OP,
00670 class CP,
00671 template <class> class KP,
00672 template <class,class> class SP,
00673 template <class> class CNP,
00674 typename U
00675 >
00676 inline bool operator<(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00677 U* rhs)
00678 {
00679 return ( GetImpl( lhs ) < rhs );
00680 }
00681
00686
00687 template
00688 <
00689 typename T,
00690 typename H,
00691 template <class> class OP,
00692 class CP,
00693 template <class> class KP,
00694 template <class,class> class SP,
00695 template <class> class CNP,
00696 typename U
00697 >
00698 inline bool operator<(U* lhs,
00699 const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
00700 {
00701 return ( GetImpl( rhs ) < lhs );
00702 }
00703
00705
00708
00709 template
00710 <
00711 typename T,
00712 typename H,
00713 template <class> class OP,
00714 class CP,
00715 template <class> class KP,
00716 template <class,class> class SP,
00717 template <class> class CNP,
00718 typename U
00719 >
00720 inline bool operator>(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00721 U* rhs)
00722 { return rhs < lhs; }
00723
00728
00729 template
00730 <
00731 typename T,
00732 typename H,
00733 template <class> class OP,
00734 class CP,
00735 template <class> class KP,
00736 template <class,class> class SP,
00737 template <class> class CNP,
00738 typename U
00739 >
00740 inline bool operator>(U* lhs,
00741 const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
00742 { return rhs < lhs; }
00743
00748
00749 template
00750 <
00751 typename T,
00752 typename H,
00753 template <class> class OP,
00754 class CP,
00755 template <class> class KP,
00756 template <class,class> class SP,
00757 template <class> class CNP,
00758 typename U
00759 >
00760 inline bool operator<=(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00761 U* rhs)
00762 { return !(rhs < lhs); }
00763
00768
00769 template
00770 <
00771 typename T,
00772 typename H,
00773 template <class> class OP,
00774 class CP,
00775 template <class> class KP,
00776 template <class,class> class SP,
00777 template <class> class CNP,
00778 typename U
00779 >
00780 inline bool operator<=(U* lhs,
00781 const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
00782 { return !(rhs < lhs); }
00783
00788
00789 template
00790 <
00791 typename T,
00792 typename H,
00793 template <class> class OP,
00794 class CP,
00795 template <class> class KP,
00796 template <class,class> class SP,
00797 template <class> class CNP,
00798 typename U
00799 >
00800 inline bool operator>=(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00801 U* rhs)
00802 { return !(lhs < rhs); }
00803
00808
00809 template
00810 <
00811 typename T,
00812 typename H,
00813 template <class> class OP,
00814 class CP,
00815 template <class> class KP,
00816 template <class,class> class SP,
00817 template <class> class CNP,
00818 typename U
00819 >
00820 inline bool operator>=(U* lhs,
00821 const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
00822 { return !(lhs < rhs); }
00823
00824 };
00825
00830
00831 namespace std
00832 {
00833 template
00834 <
00835 typename T,
00836 typename H,
00837 template <class> class OP,
00838 class CP,
00839 template <class> class KP,
00840 template <class,class> class SP,
00841 template <class> class CNP
00842 >
00843 struct less< maci::SmartPtr<T, H, OP, CP, KP, SP, CNP > >
00844 : public binary_function<maci::SmartPtr<T, H, OP, CP, KP, SP, CNP >,
00845 maci::SmartPtr<T, H, OP, CP, KP, SP, CNP >, bool>
00846 {
00847 bool operator()(const maci::SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00848 const maci::SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs) const
00849 { return less<T*>()(GetImpl(lhs), GetImpl(rhs)); }
00850 };
00851 };
00852
00853 #endif