• Classes
  • Modules
  • Namespaces
  • Files
  • Related Pages
  • File List
  • File Members

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.14 2010/07/17 20:43:02 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 #include <ACSErrTypeCommon.h>
00047 
00048 namespace maci {
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(false), pointee_(Default())
00068         {}
00069 
00073     ComponentStorage(const StoredType& p) : handle(0), sticky(false), 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_(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     // 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 
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     // Default value to initialize the pointer
00196     static StoredType Default()
00197         { return T::_nil(); }
00198 
00199   private:
00200     // Data
00201     H *handle;
00202     bool sticky;
00203     StoredType pointee_;
00204 };
00205 
00206 
00207 class ContainerServices;
00208 
00209 
00210 /******************************************************************************
00211  * The code below was taken from the lokiSmartPtr.h file, which is covered
00212  * by the license listed below.  It has been modified to allow two parameter
00213  * StoragePolicy classes to be used.
00214  ******************************************************************************/
00216 // The Loki Library
00217 // Copyright (c) 2001 by Andrei Alexandrescu
00218 // This code accompanies the book:
00219 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
00220 //     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
00221 // Permission to use, copy, modify, distribute and sell this software for any
00222 //     purpose is hereby granted without fee, provided that the above copyright
00223 //     notice appear in all copies and that both that copyright notice and this
00224 //     permission notice appear in supporting documentation.
00225 // The author or Addison-Wesley Longman make no representations about the
00226 //     suitability of this software for any purpose. It is provided "as is"
00227 //     without express or implied warranty.
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 // Enables "if (!sp) ..."
00446         { return GetImpl(*this) == 0; }
00447 
00448         static inline T * GetPointer( const SmartPtr & sp )
00449         { return GetImpl( sp ); }
00450 
00451         // Ambiguity buster
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         // Ambiguity buster
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         // Ambiguity buster
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         // 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( rhs ) < GetImpl( *this ) );
00523         }
00524 
00525         // Ambiguity buster
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         // Helper for enabling 'if (sp)'
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         // enable 'if (sp)'
00556         operator unspecified_boolean_type() const
00557         {
00558             return !*this ? 0 : &Tester::dummy;
00559         }
00560 
00561     private:
00562         // Helper for disallowing automatic conversion
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 // free comparison operators for class template SmartPtr
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 //  operator> for lhs = SmartPtr, rhs = raw pointer
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 /* ACSSMARTPOINTER_H */

Generated on Thu Jan 12 2012 23:13:50 for ACS-10.0 C++ API by  doxygen 1.7.0