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)
00157 { return sp.isNil() || sp.handle != (H *)0; }
00158
00163 bool inline isNil()
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 friend inline void Release(SmartPtr& sp, typename SP::StoredType& p)
00403 {
00404 p = GetImplRef(sp);
00405 GetImplRef(sp) = SP::Default();
00406 }
00407
00408 friend inline void Reset(SmartPtr& sp, typename SP::StoredType p)
00409 { SmartPtr(p).Swap(sp); }
00410
00411 template
00412 <
00413 typename T1,
00414 typename H1,
00415 template <class> class OP1,
00416 class CP1,
00417 template <class> class KP1,
00418 template <class,class> class SP1,
00419 template <class> class CNP1
00420 >
00421 bool Merge( SmartPtr< T1, H1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
00422 {
00423 if ( GetImpl( *this ) != GetImpl( rhs ) )
00424 {
00425 return false;
00426 }
00427 return OP::Merge( rhs );
00428 }
00429
00430 PointerType operator->()
00431 {
00432 KP::OnDereference(GetImplRef(*this));
00433 return SP::operator->();
00434 }
00435
00436 ConstPointerType operator->() const
00437 {
00438 KP::OnDereference(GetImplRef(*this));
00439 return SP::operator->();
00440 }
00441
00442 ReferenceType operator*()
00443 {
00444 KP::OnDereference(GetImplRef(*this));
00445 return SP::operator*();
00446 }
00447
00448 ConstReferenceType operator*() const
00449 {
00450 KP::OnDereference(GetImplRef(*this));
00451 return SP::operator*();
00452 }
00453
00454 bool operator!() const
00455 { return GetImpl(*this) == 0; }
00456
00457 static inline T * GetPointer( const SmartPtr & sp )
00458 { return GetImpl( sp ); }
00459
00460
00461 template
00462 <
00463 typename T1,
00464 typename H1,
00465 template <class> class OP1,
00466 class CP1,
00467 template <class> class KP1,
00468 template <class,class> class SP1,
00469 template <class> class CNP1
00470 >
00471 bool operator==(const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const
00472 { return GetImpl(*this) == GetImpl(rhs); }
00473
00474
00475 template
00476 <
00477 typename T1,
00478 typename H1,
00479 template <class> class OP1,
00480 class CP1,
00481 template <class> class KP1,
00482 template <class,class> class SP1,
00483 template <class> class CNP1
00484 >
00485 bool operator!=(const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const
00486 { return !(*this == rhs); }
00487
00488
00489 template
00490 <
00491 typename T1,
00492 typename H1,
00493 template <class> class OP1,
00494 class CP1,
00495 template <class> class KP1,
00496 template <class,class> class SP1,
00497 template <class> class CNP1
00498 >
00499 bool operator<(const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const
00500 { return GetImpl(*this) < GetImpl(rhs); }
00501
00502
00503 template
00504 <
00505 typename T1,
00506 typename H1,
00507 template <class> class OP1,
00508 class CP1,
00509 template <class> class KP1,
00510 template <class,class> class SP1,
00511 template <class> class CNP1
00512 >
00513 inline bool operator > ( const SmartPtr< T1, H1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
00514 {
00515 return ( GetImpl( rhs ) < GetImpl( *this ) );
00516 }
00517
00518
00519 template
00520 <
00521 typename T1,
00522 typename H1,
00523 template <class> class OP1,
00524 class CP1,
00525 template <class> class KP1,
00526 template <class,class> class SP1,
00527 template <class> class CNP1
00528 >
00529 inline bool operator <= ( const SmartPtr< T1, H1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
00530 {
00531 return !( GetImpl( rhs ) < GetImpl( *this ) );
00532 }
00533
00534
00535 template
00536 <
00537 typename T1,
00538 typename H1,
00539 template <class> class OP1,
00540 class CP1,
00541 template <class> class KP1,
00542 template <class,class> class SP1,
00543 template <class> class CNP1
00544 >
00545 inline bool operator >= ( const SmartPtr< T1, H1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
00546 {
00547 return !( GetImpl( *this ) < GetImpl( rhs ) );
00548 }
00549
00550 private:
00551
00552 struct Tester
00553 {
00554 Tester(int) {}
00555 void dummy() {}
00556 };
00557
00558 typedef void (Tester::*unspecified_boolean_type_)();
00559
00560 typedef typename Loki::Select<CP::allow, Tester, unspecified_boolean_type_>::Result
00561 unspecified_boolean_type;
00562
00563 public:
00564
00565 operator unspecified_boolean_type() const
00566 {
00567 return !*this ? 0 : &Tester::dummy;
00568 }
00569
00570 private:
00571
00572 struct Insipid
00573 {
00574 Insipid(PointerType) {}
00575 };
00576
00577 typedef typename Loki::Select<CP::allow, PointerType, Insipid>::Result
00578 AutomaticConversionResult;
00579
00580 public:
00581 operator AutomaticConversionResult() const
00582 { return GetImpl(*this); }
00583 };
00584
00586
00588
00593
00594 template
00595 <
00596 typename T,
00597 typename H,
00598 template <class> class OP,
00599 class CP,
00600 template <class> class KP,
00601 template <class,class> class SP,
00602 template <class> class CNP1,
00603 typename U
00604 >
00605 inline bool operator==(const SmartPtr<T, H, OP, CP, KP, SP, CNP1 >& lhs,
00606 U* rhs)
00607 { return GetImpl(lhs) == rhs; }
00608
00613
00614 template
00615 <
00616 typename T,
00617 typename H,
00618 template <class> class OP,
00619 class CP,
00620 template <class> class KP,
00621 template <class,class> class SP,
00622 template <class> class CNP1,
00623 typename U
00624 >
00625 inline bool operator==(U* lhs,
00626 const SmartPtr<T, H, OP, CP, KP, SP, CNP1 >& rhs)
00627 { return rhs == lhs; }
00628
00633
00634 template
00635 <
00636 typename T,
00637 typename H,
00638 template <class> class OP,
00639 class CP,
00640 template <class> class KP,
00641 template <class,class> class SP,
00642 template <class> class CNP,
00643 typename U
00644 >
00645 inline bool operator!=(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00646 U* rhs)
00647 { return !(lhs == rhs); }
00648
00653
00654 template
00655 <
00656 typename T,
00657 typename H,
00658 template <class> class OP,
00659 class CP,
00660 template <class> class KP,
00661 template <class,class> class SP,
00662 template <class> class CNP,
00663 typename U
00664 >
00665 inline bool operator!=(U* lhs,
00666 const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
00667 { return rhs != lhs; }
00668
00673
00674 template
00675 <
00676 typename T,
00677 typename H,
00678 template <class> class OP,
00679 class CP,
00680 template <class> class KP,
00681 template <class,class> class SP,
00682 template <class> class CNP,
00683 typename U
00684 >
00685 inline bool operator<(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00686 U* rhs)
00687 {
00688 return ( GetImpl( lhs ) < rhs );
00689 }
00690
00695
00696 template
00697 <
00698 typename T,
00699 typename H,
00700 template <class> class OP,
00701 class CP,
00702 template <class> class KP,
00703 template <class,class> class SP,
00704 template <class> class CNP,
00705 typename U
00706 >
00707 inline bool operator<(U* lhs,
00708 const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
00709 {
00710 return ( GetImpl( rhs ) < lhs );
00711 }
00712
00714
00717
00718 template
00719 <
00720 typename T,
00721 typename H,
00722 template <class> class OP,
00723 class CP,
00724 template <class> class KP,
00725 template <class,class> class SP,
00726 template <class> class CNP,
00727 typename U
00728 >
00729 inline bool operator>(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00730 U* rhs)
00731 { return rhs < lhs; }
00732
00737
00738 template
00739 <
00740 typename T,
00741 typename H,
00742 template <class> class OP,
00743 class CP,
00744 template <class> class KP,
00745 template <class,class> class SP,
00746 template <class> class CNP,
00747 typename U
00748 >
00749 inline bool operator>(U* lhs,
00750 const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
00751 { return rhs < lhs; }
00752
00757
00758 template
00759 <
00760 typename T,
00761 typename H,
00762 template <class> class OP,
00763 class CP,
00764 template <class> class KP,
00765 template <class,class> class SP,
00766 template <class> class CNP,
00767 typename U
00768 >
00769 inline bool operator<=(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00770 U* rhs)
00771 { return !(rhs < lhs); }
00772
00777
00778 template
00779 <
00780 typename T,
00781 typename H,
00782 template <class> class OP,
00783 class CP,
00784 template <class> class KP,
00785 template <class,class> class SP,
00786 template <class> class CNP,
00787 typename U
00788 >
00789 inline bool operator<=(U* lhs,
00790 const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
00791 { return !(rhs < lhs); }
00792
00797
00798 template
00799 <
00800 typename T,
00801 typename H,
00802 template <class> class OP,
00803 class CP,
00804 template <class> class KP,
00805 template <class,class> class SP,
00806 template <class> class CNP,
00807 typename U
00808 >
00809 inline bool operator>=(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00810 U* rhs)
00811 { return !(lhs < rhs); }
00812
00817
00818 template
00819 <
00820 typename T,
00821 typename H,
00822 template <class> class OP,
00823 class CP,
00824 template <class> class KP,
00825 template <class,class> class SP,
00826 template <class> class CNP,
00827 typename U
00828 >
00829 inline bool operator>=(U* lhs,
00830 const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
00831 { return !(lhs < rhs); }
00832
00833 };
00834
00839
00840 namespace std
00841 {
00842 template
00843 <
00844 typename T,
00845 typename H,
00846 template <class> class OP,
00847 class CP,
00848 template <class> class KP,
00849 template <class,class> class SP,
00850 template <class> class CNP
00851 >
00852 struct less< maci::SmartPtr<T, H, OP, CP, KP, SP, CNP > >
00853 : public binary_function<maci::SmartPtr<T, H, OP, CP, KP, SP, CNP >,
00854 maci::SmartPtr<T, H, OP, CP, KP, SP, CNP >, bool>
00855 {
00856 bool operator()(const maci::SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00857 const maci::SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs) const
00858 { return less<T*>()(GetImpl(lhs), GetImpl(rhs)); }
00859 };
00860 };
00861
00862 #endif