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