coherence/lang/FinalHandle.hpp

00001 /*
00002 * FinalHandle.hpp
00003 *
00004 * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
00005 *
00006 * Oracle is a registered trademarks of Oracle Corporation and/or its
00007 * affiliates.
00008 *
00009 * This software is the confidential and proprietary information of Oracle
00010 * Corporation. You shall not disclose such confidential and proprietary
00011 * information and shall use it only in accordance with the terms of the
00012 * license agreement you entered into with Oracle.
00013 *
00014 * This notice may not be removed or altered.
00015 */
00016 #ifndef COH_FINAL_HANDLE_HPP
00017 #define COH_FINAL_HANDLE_HPP
00018 
00019 #include "coherence/lang/compatibility.hpp"
00020 
00021 #include "coherence/lang/MemberHandle.hpp"
00022 #include "coherence/lang/TypedHandle.hpp"
00023 
00024 COH_OPEN_NAMESPACE2(coherence,lang)
00025 
00026 /**
00027 * FinalHandle is an immutable thread-safe handle used by an Object to
00028 * reference its non-const child Objects.
00029 *
00030 * FinalHandles may either be initialized with a value at
00031 * construction-time, or thereafter via the initialize() function.  A
00032 * FinalHandle may be initialized only if the following conditions
00033 * hold:
00034 * <ul>
00035 *   <li> The FinalHandle has not already been initialized
00036 *   (either during construction, or via <tt>initialize()</tt>)
00037 *   <li> The FinalHandle has not escaped
00038 * </ul>
00039 * For example:
00040 *
00041 * @code
00042 * class Foo
00043 *   : public class_spec<Foo>
00044 *   {
00045 *   friend class factory<Foo>;
00046 *
00047 *   protected:
00048 *     Foo()
00049 *       : m_fhBar(self()) // construction without initialization
00050 *       {}
00051 *
00052 *   public:
00053 *     void setBar(Bar::Handle hBar)
00054 *       {
00055 *       initialize(m_fhBar, hBar); // post-construction initialization
00056 *       }
00057 *
00058 *   private:
00059 *     FinalHandle<Bar> m_fhBar;
00060 *   };
00061 * @endcode
00062 *
00063 * FinalHandles transfer the constness of their parent Object. When a
00064 * FinalHandle is accessed from within a const method of the enclosing
00065 * "parent" class, it will only provide const access to the Object which it
00066 * references. If the enclosing Object becomes only accessed via views the
00067 * FinalHandle will also automatically, and permanently switch its reference
00068 * type from a handle to a view.
00069 *
00070 * Note: In the rare case that a FinalHandle is declared via the mutable
00071 *       keyword, the FinalHandle must be informed of this fact by setting
00072 *       fMutable to true during construction.  A mutable FinalHandle will
00073 *       will return Handles from const methods of the class it is a data
00074 *       member of.  The FinalHandle cannot be reassigned to reference another
00075 *       object.
00076 *
00077 * @author mf  2008.12.01
00078 *
00079 * @see FinalView
00080 * @see FinalHolder
00081 */
00082 template<class T>
00083 class FinalHandle
00084     : public MemberHandle<T>
00085     {
00086     // ----- typedefs -------------------------------------------------------
00087 
00088     public:
00089         /**
00090         * The type of the values the holder can reference.
00091         */
00092         typedef T ValueType;
00093 
00094         /**
00095         * The Handle type for the referenced Object.
00096         */
00097         typedef typename T::Handle ValueHandle;
00098 
00099         /**
00100         * The View type for the referenced Object.
00101         */
00102         typedef typename T::View ValueView;
00103 
00104 
00105     // -------- constructors ------------------------------------------------
00106 
00107     public:
00108         /**
00109         * Construct a new FinalHandle referencing NULL via a handle.
00110         *
00111         * @param oGuardian  the object that protects this member
00112         */
00113         FinalHandle(const Object& oGuardian)
00114             : MemberHandle<T>(oGuardian)
00115             {
00116             }
00117 
00118         /**
00119         * Construct a new FinalHandle referencing specified Object.
00120         *
00121         * @param oGuardian  the object that protects this member
00122         * @param that       the object to reference
00123         */
00124         FinalHandle(const Object& oGuardian, const ValueHandle& that)
00125             : MemberHandle<T>(oGuardian, that)
00126             {
00127             // Note: The underlying MemberHandle is initialized in the
00128             // INHERITED mutability state, allowing the FinalHandle to act
00129             // as a handle in non-const methods.
00130             }
00131 
00132         /**
00133         * Construct a new FinalHandle referencing specified Object.
00134         *
00135         * @param oGuardian  the object that protects this member
00136         * @param that       the object to reference
00137         * @param fMutable   true if the member is declared as mutable, false
00138         *                   if declared as const
00139         */
00140         FinalHandle(const Object& oGuardian, const ValueHandle& that, bool fMutable)
00141             : MemberHandle<T>(oGuardian, that, fMutable)
00142             {
00143             }
00144 
00145 
00146     // ----- operators ------------------------------------------------------
00147 
00148     public:
00149         /**
00150         * Return a View to the referenced Object.
00151         *
00152         * @return a View to the referenced Object
00153         */
00154         operator ValueView() const
00155             {
00156             return ValueView(MemberHandle<T>::m_po);
00157             }
00158 
00159         /**
00160         * Return a Handle to the referenced Object.
00161         *
00162         * @return a Handle to the referenced Object
00163         */
00164         operator ValueHandle()
00165             {
00166             return ValueHandle(MemberHandle<T>::m_po);
00167             }
00168 
00169         /**
00170         * Return a View to the referenced Object.
00171         *
00172         * @return a View to the referenced Object
00173         */
00174         template<class PT>
00175         operator TypedHandle<const PT>() const
00176             {
00177             return MemberHandle<T>::m_po;
00178             }
00179 
00180         /**
00181         * Return a Handle to the referenced Object.
00182         *
00183         * @return a Handle to the referenced Object
00184         */
00185         template<class PT>
00186         operator TypedHandle<PT>()
00187             {
00188             return MemberHandle<T>::m_po;
00189             }
00190 
00191         /**
00192         * Return a TypedHolder to the referenced Object.
00193         *
00194         * @return a TypedHolder to the referenced Object
00195         *
00196         */
00197         template<class PT>
00198         operator TypedHolder<PT>() const
00199             {
00200             return ValueView(MemberHandle<T>::m_po);
00201             }
00202 
00203         /**
00204         * Return a TypedHolder to the referenced Object.
00205         *
00206         * @return a TypedHolder to the referenced Object
00207         */
00208         template<class PT>
00209         operator TypedHolder<PT>()
00210             {
00211             return MemberHandle<T>::m_po;
00212             }
00213 
00214         /**
00215         * Dereference the FinalHandle.
00216         *
00217         * @return a const pointer to the referenced Object
00218         */
00219         const T* operator->() const
00220             {
00221             const T* cpo = MemberHandle<T>::m_po;
00222             if (NULL == cpo)
00223                 {
00224                 coh_throw_npe(typeid(const T));
00225                 }
00226             return cpo;
00227             }
00228 
00229         /**
00230         * Dereference the FinalHandle.
00231         *
00232         * @return a const pointer to the referenced Object
00233         */
00234         T* operator->()
00235             {
00236             if (MemberHandle<T>::m_nMutability >= MemberHandle<T>::CONST)
00237                 {
00238                 coh_throw_illegal_state(
00239                     "attempt to access handle from const FinalHandle");
00240                 }
00241 
00242             T* po = MemberHandle<T>::m_po;
00243             if (NULL == po)
00244                 {
00245                 coh_throw_npe(typeid(T));
00246                 }
00247             return po;
00248             }
00249 
00250     private:
00251         /**
00252         * Blocked assignment operator.
00253         */
00254         FinalHandle& operator=(const ValueHandle& that);
00255 
00256         /**
00257         * Blocked assignment operator.
00258         */
00259         FinalHandle& operator=(const FinalHandle<T>& that);
00260 
00261         /**
00262         * Blocked assignment operator.
00263         */
00264         FinalHandle& operator=(FinalHandle<T>& that);
00265 
00266 
00267     // ----- helper methods -------------------------------------------------
00268 
00269     protected:
00270         /**
00271         * Initialize the value of a FinalHandle after it is
00272         * constructed.  A FinalHandle may be initialized only if the
00273         * following conditions hold:
00274         * <ul>
00275         *   <li> The FinalHandle has not already been initialized
00276         *   (either during construction, or via <tt>initialize()</tt>)
00277         *   <li> The FinalHandle has not escaped
00278         * </ul>
00279         *
00280         * @param that  the value to initialize this FinalHandle to
00281         */
00282         void initialize(ValueHandle that)
00283             {
00284             if (MemberHandle<T>::m_po != NULL)
00285                 {
00286                 coh_throw_illegal_state(
00287                     "attempt to multiply initialize FinalHandle");
00288                 }
00289             if (MemberHandle<T>::getGuardian()._isEscaped())
00290                 {
00291                 coh_throw_illegal_state(
00292                     "attempt to initialize FinalHandle after it has escaped");
00293                 }
00294             if (MemberHandle<T>::m_nMutability >= MemberHandle<T>::CONST)
00295                 {
00296                 coh_throw_illegal_state(
00297                     "attempt to initialize const FinalHandle");
00298                 }
00299 
00300             T* po = get_pointer(that);
00301             MemberHandle<T>::m_po =
00302                 NULL == po || NULL == po->_attach(/*fEscaped*/ false)
00303                     ? NULL : po;
00304             }
00305 
00306     // ----- friends --------------------------------------------------------
00307 
00308     /**
00309     * @internal
00310     */
00311     template<class _T, class H> friend void initialize(FinalHandle<_T>& fh,
00312                                               H that);
00313     };
00314 
00315 /**
00316 * Perform a dynamic cast the pointer associated with the FinalHandle
00317 * to a the specified handle/view type.
00318 *
00319 * @param h       the FinalHandle from which to perform the cast
00320 * @param fThrow  true if an exception is to be thrown on a failed cast
00321 *
00322 * @return the casted pointer, or NULL if the cast fails and fThrow is false
00323 *
00324 * @throws ClassCastException if the cast fails and fThrow is true
00325 */
00326 template<class D, class T>
00327 D cast(FinalHandle<T>& h, bool fThrow = true)
00328     {
00329     return cast<D>((typename FinalHandle<T>::ValueHandle) h, fThrow);
00330     }
00331 
00332 /**
00333 * Perform a dynamic cast the pointer associated with the FinalHandle
00334 * to a the specified handle/view type.
00335 *
00336 * @param h       the FinalHandle from which to perform the cast
00337 * @param fThrow  true if an exception is to be thrown on a failed cast
00338 *
00339 * @return the casted pointer, or NULL if the cast fails and fThrow is false
00340 *
00341 * @throws ClassCastException if the cast fails and fThrow is true
00342 */
00343 template<class D, class T>
00344 D cast(const FinalHandle<T>& h, bool fThrow = true)
00345     {
00346     return cast<D>((typename FinalHandle<T>::ValueView) h, fThrow);
00347     }
00348 
00349 /**
00350 * Perform an instanceof check on a FinalHandle.
00351 *
00352 * @param h   the FinalHandle from which to perform the test
00353 *
00354 * @return true if the supplied handle is an instance of the specified type
00355 */
00356 template<class D, class T>
00357 bool instanceof(FinalHandle<T>& h)
00358     {
00359     return NULL != cast<D>(h, false);
00360     }
00361 
00362 /**
00363 * Perform an instanceof check on a FinalHandle.
00364 *
00365 * @param h   the FinalHandle from which to perform the test
00366 *
00367 * @return true if the supplied handle is an instance of the specified type
00368 */
00369 template<class D, class T>
00370 bool instanceof(const FinalHandle<T>& h)
00371     {
00372     return NULL != cast<D>(h, false);
00373     }
00374 
00375 /**
00376 * Initialize the value of a FinalHandle after it is constructed.  A
00377 * FinalHandle may be initialized only if the following conditions
00378 * hold:
00379 * <ul>
00380 *   <li> The FinalHandle has not already been initialized to a
00381 *   non-NULL value (either during construction, or via
00382 *   <tt>initialize()</tt>)
00383 *   <li> The FinalHandle has not escaped
00384 * </ul>
00385 *
00386 * @param h     the FinalHandle to initialize
00387 * @param that  the value to initialize this FinalHandle to
00388 */
00389 template<class T, class H>
00390 void initialize(FinalHandle<T>& h, H that)
00391     {
00392     h.initialize(that);
00393     }
00394 
00395 COH_CLOSE_NAMESPACE2
00396 
00397 #endif // COH_FINAL_HANDLE_HPP
Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.