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
00047 namespace maci {
00048
00055 template <class T, class H>
00056 class ComponentStorage
00057 {
00058 public:
00059 typedef T* StoredType;
00060 typedef T* PointerType;
00061 typedef T& ReferenceType;
00062
00066 ComponentStorage() : handle(0), sticky(false), pointee_(Default())
00067 {}
00068
00072 ComponentStorage(const StoredType& p) : handle(0), sticky(false), pointee_(p)
00073 {}
00074
00075
00076
00080 ComponentStorage(const ComponentStorage& rhs) : handle(rhs.handle), sticky(rhs.sticky), pointee_(0)
00081 {}
00082
00087 template <typename U, typename V>
00088 ComponentStorage(const ComponentStorage<U,V>&) : handle(0), sticky(false), pointee_(0)
00089 {}
00090
00100 void setValues(H *h, bool s, const StoredType& p)
00101 {
00102 handle = h;
00103 sticky = s;
00104 pointee_ = p;
00105 };
00106
00110 PointerType operator->() const { return pointee_; }
00111
00115 ReferenceType operator*() const { return *pointee_; }
00116
00122 void Swap(ComponentStorage& rhs)
00123 {
00124 std::swap(pointee_, rhs.pointee_);
00125 std::swap(sticky, rhs.sticky);
00126 std::swap(handle, rhs.handle);
00127 }
00128
00129
00134 friend inline PointerType GetImpl(const ComponentStorage& sp)
00135 { return sp.pointee_; }
00136
00141 friend inline const StoredType& GetImplRef(const ComponentStorage& sp)
00142 { return sp.pointee_; }
00143
00148 friend inline StoredType& GetImplRef(ComponentStorage& sp)
00149 { return sp.pointee_; }
00150
00155 bool inline isValid(const ComponentStorage& sp)
00156 { return sp.handle != (H *)0; }
00157
00162 bool inline isNil()
00163 { return CORBA::is_nil(pointee_);}
00164
00165
00166 protected:
00167
00172 void Destroy()
00173 {
00174 if (handle && pointee_ && sticky)
00175 {
00176 try
00177 {
00178 handle->releaseComponent(pointee_->name());
00179 }
00180 catch(maciErrType::CannotReleaseComponentExImpl& ex)
00181 {
00182 ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ComponentStorage::Destroy",
00183 (LM_ERROR, "Unable to release component"));
00184 }
00185 catch(...)
00186 {
00187 ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ComponentStorage::Destroy",
00188 (LM_ERROR, "Unexpected exception caught when releasing component."));
00189 }
00190 }
00191 }
00192
00193
00194
00195 static StoredType Default()
00196 { return T::_nil(); }
00197
00198 private:
00199
00200 H *handle;
00201 bool sticky;
00202 StoredType pointee_;
00203 };
00204
00205
00206 class ContainerServices;
00207
00208
00209
00210
00211
00212
00213
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00228
00229 template
00230 <
00231 typename T,
00232 typename H = ContainerServices,
00233 template <class> class OwnershipPolicy = Loki::RefCountedMTAdj<Loki::ObjectLevelLockable>::RefCountedMT,
00234 class ConversionPolicy = Loki::DisallowConversion,
00235 template <class> class CheckingPolicy = Loki::NoCheck,
00236 template <class,class> class StoragePolicy = ComponentStorage,
00237 template<class> class ConstnessPolicy = Loki::LOKI_DEFAULT_CONSTNESS
00238 >
00239 class SmartPtr
00240 : public StoragePolicy<T,H>
00241 , public OwnershipPolicy<typename StoragePolicy<T,H>::PointerType>
00242 , public CheckingPolicy<typename StoragePolicy<T,H>::StoredType>
00243 , public ConversionPolicy
00244 {
00245 typedef StoragePolicy<T,H> SP;
00246 typedef OwnershipPolicy<typename StoragePolicy<T,H>::PointerType> OP;
00247 typedef CheckingPolicy<typename StoragePolicy<T,H>::StoredType> KP;
00248 typedef ConversionPolicy CP;
00249
00250 public:
00251 typedef typename ConstnessPolicy<T>::Type* ConstPointerType;
00252 typedef typename ConstnessPolicy<T>::Type& ConstReferenceType;
00253
00254 typedef typename SP::PointerType PointerType;
00255 typedef typename SP::StoredType StoredType;
00256 typedef typename SP::ReferenceType ReferenceType;
00257
00258 typedef typename Loki::Select<OP::destructiveCopy,SmartPtr, const SmartPtr>::Result CopyArg;
00259
00260 private:
00261 struct NeverMatched;
00262
00263 #ifdef LOKI_SMARTPTR_CONVERSION_CONSTRUCTOR_POLICY
00264 typedef typename Loki::Select< CP::allow, const StoredType&, NeverMatched>::Result ImplicitArg;
00265 typedef typename Loki::Select<!CP::allow, const StoredType&, NeverMatched>::Result ExplicitArg;
00266 #else
00267 typedef const StoredType& ImplicitArg;
00268 typedef typename Loki::Select<false, const StoredType&, NeverMatched>::Result ExplicitArg;
00269 #endif
00270
00271 public:
00272
00273 SmartPtr()
00274 { KP::OnDefault(GetImpl(*this)); }
00275
00283 SmartPtr(H* h, bool s, T* p)
00284 {
00285 setValues(h, s, p);
00286 }
00287
00288 SmartPtr(CopyArg& rhs)
00289 : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
00290 { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
00291
00292 template
00293 <
00294 typename T1,
00295 typename H1,
00296 template <class> class OP1,
00297 class CP1,
00298 template <class> class KP1,
00299 template <class,class> class SP1,
00300 template <class> class CNP1
00301 >
00302 SmartPtr(const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
00303 : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
00304 { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
00305
00306 template
00307 <
00308 typename T1,
00309 typename H1,
00310 template <class> class OP1,
00311 class CP1,
00312 template <class> class KP1,
00313 template <class,class> class SP1,
00314 template <class> class CNP1
00315 >
00316 SmartPtr(SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
00317 : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
00318 { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
00319
00320 SmartPtr(Loki::RefToValue<SmartPtr> rhs)
00321 : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
00322 {}
00323
00324 operator Loki::RefToValue<SmartPtr>()
00325 { return Loki::RefToValue<SmartPtr>(*this); }
00326
00327 SmartPtr& operator=(CopyArg& rhs)
00328 {
00329 SmartPtr temp(rhs);
00330 if (!isValid(rhs))
00331 throw std::invalid_argument("Attempt to use SmartPtr with no ContainerService or Client reference.");
00332 else
00333 temp.Swap(*this);
00334 return *this;
00335 }
00336
00337 template
00338 <
00339 typename T1,
00340 typename H1,
00341 template <class> class OP1,
00342 class CP1,
00343 template <class> class KP1,
00344 template <class,class> class SP1,
00345 template <class> class CNP1
00346 >
00347 SmartPtr& operator=(const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
00348 {
00349 SmartPtr temp(rhs);
00350 if (!isValid(rhs))
00351 throw std::invalid_argument("Attempt to use SmartPtr with no ContainerService or Client reference.");
00352 else
00353 temp.Swap(*this);
00354 return *this;
00355 }
00356
00357 template
00358 <
00359 typename T1,
00360 typename H1,
00361 template <class> class OP1,
00362 class CP1,
00363 template <class> class KP1,
00364 template <class,class> class SP1,
00365 template <class> class CNP1
00366 >
00367 SmartPtr& operator=(SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
00368 {
00369 SmartPtr temp(rhs);
00370 if (!isValid(rhs))
00371 throw std::invalid_argument("Attempt to use SmartPtr with no ContainerService or Client reference.");
00372 else
00373 temp.Swap(*this);
00374 return *this;
00375 }
00376
00377 void Swap(SmartPtr& rhs)
00378 {
00379 OP::Swap(rhs);
00380 CP::Swap(rhs);
00381 KP::Swap(rhs);
00382 SP::Swap(rhs);
00383 }
00384
00385 ~SmartPtr()
00386 {
00387 if (!SP::isNil() && OP::Release(GetImpl(*static_cast<SP*>(this))))
00388 {
00389 SP::Destroy();
00390 }
00391 }
00392
00393 void release()
00394 {
00395 OP temp;
00396 this->~SmartPtr();
00397 this->setValues((H *)0, false, SP::Default());
00398 OP::Swap(temp);
00399 }
00400
00401 friend inline void Release(SmartPtr& sp, typename SP::StoredType& p)
00402 {
00403 p = GetImplRef(sp);
00404 GetImplRef(sp) = SP::Default();
00405 }
00406
00407 friend inline void Reset(SmartPtr& sp, typename SP::StoredType p)
00408 { SmartPtr(p).Swap(sp); }
00409
00410 template
00411 <
00412 typename T1,
00413 typename H1,
00414 template <class> class OP1,
00415 class CP1,
00416 template <class> class KP1,
00417 template <class,class> class SP1,
00418 template <class> class CNP1
00419 >
00420 bool Merge( SmartPtr< T1, H1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
00421 {
00422 if ( GetImpl( *this ) != GetImpl( rhs ) )
00423 {
00424 return false;
00425 }
00426 return OP::Merge( rhs );
00427 }
00428
00429 PointerType operator->()
00430 {
00431 KP::OnDereference(GetImplRef(*this));
00432 return SP::operator->();
00433 }
00434
00435 ConstPointerType operator->() const
00436 {
00437 KP::OnDereference(GetImplRef(*this));
00438 return SP::operator->();
00439 }
00440
00441 ReferenceType operator*()
00442 {
00443 KP::OnDereference(GetImplRef(*this));
00444 return SP::operator*();
00445 }
00446
00447 ConstReferenceType operator*() const
00448 {
00449 KP::OnDereference(GetImplRef(*this));
00450 return SP::operator*();
00451 }
00452
00453 bool operator!() const
00454 { return GetImpl(*this) == 0; }
00455
00456 static inline T * GetPointer( const SmartPtr & sp )
00457 { return GetImpl( sp ); }
00458
00459
00460 template
00461 <
00462 typename T1,
00463 typename H1,
00464 template <class> class OP1,
00465 class CP1,
00466 template <class> class KP1,
00467 template <class,class> class SP1,
00468 template <class> class CNP1
00469 >
00470 bool operator==(const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const
00471 { return GetImpl(*this) == GetImpl(rhs); }
00472
00473
00474 template
00475 <
00476 typename T1,
00477 typename H1,
00478 template <class> class OP1,
00479 class CP1,
00480 template <class> class KP1,
00481 template <class,class> class SP1,
00482 template <class> class CNP1
00483 >
00484 bool operator!=(const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const
00485 { return !(*this == rhs); }
00486
00487
00488 template
00489 <
00490 typename T1,
00491 typename H1,
00492 template <class> class OP1,
00493 class CP1,
00494 template <class> class KP1,
00495 template <class,class> class SP1,
00496 template <class> class CNP1
00497 >
00498 bool operator<(const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const
00499 { return GetImpl(*this) < GetImpl(rhs); }
00500
00501
00502 template
00503 <
00504 typename T1,
00505 typename H1,
00506 template <class> class OP1,
00507 class CP1,
00508 template <class> class KP1,
00509 template <class,class> class SP1,
00510 template <class> class CNP1
00511 >
00512 inline bool operator > ( const SmartPtr< T1, H1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
00513 {
00514 return ( GetImpl( rhs ) < GetImpl( *this ) );
00515 }
00516
00517
00518 template
00519 <
00520 typename T1,
00521 typename H1,
00522 template <class> class OP1,
00523 class CP1,
00524 template <class> class KP1,
00525 template <class,class> class SP1,
00526 template <class> class CNP1
00527 >
00528 inline bool operator <= ( const SmartPtr< T1, H1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
00529 {
00530 return !( GetImpl( rhs ) < GetImpl( *this ) );
00531 }
00532
00533
00534 template
00535 <
00536 typename T1,
00537 typename H1,
00538 template <class> class OP1,
00539 class CP1,
00540 template <class> class KP1,
00541 template <class,class> class SP1,
00542 template <class> class CNP1
00543 >
00544 inline bool operator >= ( const SmartPtr< T1, H1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
00545 {
00546 return !( GetImpl( *this ) < GetImpl( rhs ) );
00547 }
00548
00549 private:
00550
00551 struct Tester
00552 {
00553 Tester(int) {}
00554 void dummy() {}
00555 };
00556
00557 typedef void (Tester::*unspecified_boolean_type_)();
00558
00559 typedef typename Loki::Select<CP::allow, Tester, unspecified_boolean_type_>::Result
00560 unspecified_boolean_type;
00561
00562 public:
00563
00564 operator unspecified_boolean_type() const
00565 {
00566 return !*this ? 0 : &Tester::dummy;
00567 }
00568
00569 private:
00570
00571 struct Insipid
00572 {
00573 Insipid(PointerType) {}
00574 };
00575
00576 typedef typename Loki::Select<CP::allow, PointerType, Insipid>::Result
00577 AutomaticConversionResult;
00578
00579 public:
00580 operator AutomaticConversionResult() const
00581 { return GetImpl(*this); }
00582 };
00583
00585
00587
00592
00593 template
00594 <
00595 typename T,
00596 typename H,
00597 template <class> class OP,
00598 class CP,
00599 template <class> class KP,
00600 template <class,class> class SP,
00601 template <class> class CNP1,
00602 typename U
00603 >
00604 inline bool operator==(const SmartPtr<T, H, OP, CP, KP, SP, CNP1 >& lhs,
00605 U* rhs)
00606 { return GetImpl(lhs) == rhs; }
00607
00612
00613 template
00614 <
00615 typename T,
00616 typename H,
00617 template <class> class OP,
00618 class CP,
00619 template <class> class KP,
00620 template <class,class> class SP,
00621 template <class> class CNP1,
00622 typename U
00623 >
00624 inline bool operator==(U* lhs,
00625 const SmartPtr<T, H, OP, CP, KP, SP, CNP1 >& rhs)
00626 { return rhs == lhs; }
00627
00632
00633 template
00634 <
00635 typename T,
00636 typename H,
00637 template <class> class OP,
00638 class CP,
00639 template <class> class KP,
00640 template <class,class> class SP,
00641 template <class> class CNP,
00642 typename U
00643 >
00644 inline bool operator!=(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00645 U* rhs)
00646 { return !(lhs == rhs); }
00647
00652
00653 template
00654 <
00655 typename T,
00656 typename H,
00657 template <class> class OP,
00658 class CP,
00659 template <class> class KP,
00660 template <class,class> class SP,
00661 template <class> class CNP,
00662 typename U
00663 >
00664 inline bool operator!=(U* lhs,
00665 const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
00666 { return rhs != lhs; }
00667
00672
00673 template
00674 <
00675 typename T,
00676 typename H,
00677 template <class> class OP,
00678 class CP,
00679 template <class> class KP,
00680 template <class,class> class SP,
00681 template <class> class CNP,
00682 typename U
00683 >
00684 inline bool operator<(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00685 U* rhs)
00686 {
00687 return ( GetImpl( lhs ) < rhs );
00688 }
00689
00694
00695 template
00696 <
00697 typename T,
00698 typename H,
00699 template <class> class OP,
00700 class CP,
00701 template <class> class KP,
00702 template <class,class> class SP,
00703 template <class> class CNP,
00704 typename U
00705 >
00706 inline bool operator<(U* lhs,
00707 const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
00708 {
00709 return ( GetImpl( rhs ) < lhs );
00710 }
00711
00713
00716
00717 template
00718 <
00719 typename T,
00720 typename H,
00721 template <class> class OP,
00722 class CP,
00723 template <class> class KP,
00724 template <class,class> class SP,
00725 template <class> class CNP,
00726 typename U
00727 >
00728 inline bool operator>(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00729 U* rhs)
00730 { return rhs < lhs; }
00731
00736
00737 template
00738 <
00739 typename T,
00740 typename H,
00741 template <class> class OP,
00742 class CP,
00743 template <class> class KP,
00744 template <class,class> class SP,
00745 template <class> class CNP,
00746 typename U
00747 >
00748 inline bool operator>(U* lhs,
00749 const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
00750 { return rhs < lhs; }
00751
00756
00757 template
00758 <
00759 typename T,
00760 typename H,
00761 template <class> class OP,
00762 class CP,
00763 template <class> class KP,
00764 template <class,class> class SP,
00765 template <class> class CNP,
00766 typename U
00767 >
00768 inline bool operator<=(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00769 U* rhs)
00770 { return !(rhs < lhs); }
00771
00776
00777 template
00778 <
00779 typename T,
00780 typename H,
00781 template <class> class OP,
00782 class CP,
00783 template <class> class KP,
00784 template <class,class> class SP,
00785 template <class> class CNP,
00786 typename U
00787 >
00788 inline bool operator<=(U* lhs,
00789 const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
00790 { return !(rhs < lhs); }
00791
00796
00797 template
00798 <
00799 typename T,
00800 typename H,
00801 template <class> class OP,
00802 class CP,
00803 template <class> class KP,
00804 template <class,class> class SP,
00805 template <class> class CNP,
00806 typename U
00807 >
00808 inline bool operator>=(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00809 U* rhs)
00810 { return !(lhs < rhs); }
00811
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 typename U
00827 >
00828 inline bool operator>=(U* lhs,
00829 const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
00830 { return !(lhs < rhs); }
00831
00832 };
00833
00838
00839 namespace std
00840 {
00841 template
00842 <
00843 typename T,
00844 typename H,
00845 template <class> class OP,
00846 class CP,
00847 template <class> class KP,
00848 template <class,class> class SP,
00849 template <class> class CNP
00850 >
00851 struct less< maci::SmartPtr<T, H, OP, CP, KP, SP, CNP > >
00852 : public binary_function<maci::SmartPtr<T, H, OP, CP, KP, SP, CNP >,
00853 maci::SmartPtr<T, H, OP, CP, KP, SP, CNP >, bool>
00854 {
00855 bool operator()(const maci::SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00856 const maci::SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs) const
00857 { return less<T*>()(GetImpl(lhs), GetImpl(rhs)); }
00858 };
00859 };
00860
00861 #endif