Oracle Fusion Middleware C++ API Reference for Oracle Coherence
12c (12.1.2)

E26041-01

coherence/lang/FinalHandle.hpp

00001 /*
00002 * FinalHandle.hpp
00003 *
00004 * Copyright (c) 2000, 2013, 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 #include "coherence/lang/SynchronizedMemberWriteBlock.hpp"
00024 
00025 
00026 COH_OPEN_NAMESPACE2(coherence,lang)
00027 
00028 /**
00029 * FinalHandle is an immutable thread-safe handle used by an Object to
00030 * reference its non-const child Objects.
00031 *
00032 * FinalHandles may either be initialized with a value at
00033 * construction-time, or thereafter via the initialize() function.  A
00034 * FinalHandle may be initialized only if the following conditions
00035 * hold:
00036 * <ul>
00037 *   <li> The FinalHandle has not already been initialized
00038 *   (either during construction, or via <tt>initialize()</tt>)
00039 * </ul>
00040 * For example:
00041 *
00042 * @code
00043 * class Foo
00044 *   : public class_spec<Foo>
00045 *   {
00046 *   friend class factory<Foo>;
00047 *
00048 *   protected:
00049 *     Foo()
00050 *       : f_hBar(self()) // construction without initialization
00051 *       {}
00052 *
00053 *   public:
00054 *     void setBar(Bar::Handle hBar)
00055 *       {
00056 *       initialize(f_hBar, hBar); // post-construction initialization
00057 *       }
00058 *
00059 *   private:
00060 *     FinalHandle<Bar> f_hBar;
00061 *   };
00062 * @endcode
00063 *
00064 * FinalHandles transfer the constness of their parent Object. When a
00065 * FinalHandle is accessed from within a const method of the enclosing
00066 * "parent" class, it will only provide const access to the Object which it
00067 * references. If the enclosing Object becomes only accessed via views the
00068 * FinalHandle will also automatically, and permanently switch its reference
00069 * type from a handle to a view.
00070 *
00071 * Note: In the rare case that a FinalHandle is declared via the mutable
00072 *       keyword, the FinalHandle must be informed of this fact by setting
00073 *       fMutable to true during construction.  A mutable FinalHandle will
00074 *       will return Handles from const methods of the class it is a data
00075 *       member of.  The FinalHandle cannot be reassigned to reference another
00076 *       object.
00077 *
00078 * @author mf  2008.12.01
00079 *
00080 * @see FinalView
00081 * @see FinalHolder
00082 */
00083 template<class T>
00084 class FinalHandle
00085     : public MemberHandle<T>
00086     {
00087     // ----- typedefs -------------------------------------------------------
00088 
00089     public:
00090         /**
00091         * The type of the values the holder can reference.
00092         */
00093         typedef T ValueType;
00094 
00095         /**
00096         * The Handle type for the referenced Object.
00097         */
00098         typedef typename T::Handle ValueHandle;
00099 
00100         /**
00101         * The View type for the referenced Object.
00102         */
00103         typedef typename T::View ValueView;
00104 
00105 
00106     // -------- constructors ------------------------------------------------
00107 
00108     public:
00109         /**
00110         * Construct a new FinalHandle referencing NULL via a handle.
00111         *
00112         * @param oGuardian  the object that protects this member
00113         */
00114         FinalHandle(const Object& oGuardian)
00115             : MemberHandle<T>(oGuardian)
00116             {
00117             }
00118 
00119         /**
00120         * Construct a new FinalHandle referencing specified Object.
00121         *
00122         * @param oGuardian  the object that protects this member
00123         * @param that       the object to reference
00124         */
00125         FinalHandle(const Object& oGuardian, const ValueHandle& that)
00126             : MemberHandle<T>(oGuardian, that)
00127             {
00128             // Note: The underlying MemberHandle is initialized in the
00129             // inherited mutability state, allowing the FinalHandle to act
00130             // as a handle in non-const methods.
00131             if (MemberHandle<T>::m_po)
00132                 {
00133                 MemberHandle<T>::m_nMutability = MemberHandle<T>::safe_immutable;
00134                 }
00135             }
00136 
00137         /**
00138         * Construct a new FinalHandle referencing specified Object.
00139         *
00140         * @param oGuardian  the object that protects this member
00141         * @param that       the object to reference
00142         * @param fMutable   true if the member is declared as mutable, false
00143         *                   if declared as const
00144         */
00145         FinalHandle(const Object& oGuardian, const ValueHandle& that, bool fMutable)
00146             : MemberHandle<T>(oGuardian, that, fMutable)
00147             {
00148             if (MemberHandle<T>::m_po && !fMutable)
00149                 {
00150                 MemberHandle<T>::m_nMutability = MemberHandle<T>::safe_immutable;
00151                 }
00152             }
00153 
00154     private:
00155         /**
00156         * Blocked copy constructor
00157         */
00158         FinalHandle(const FinalHandle&);
00159 
00160 
00161     // ----- operators ------------------------------------------------------
00162 
00163     public:
00164         /**
00165         * Return a View to the referenced Object.
00166         *
00167         * @return a View to the referenced Object
00168         */
00169         operator ValueView() const
00170             {
00171             return getFinal();
00172             }
00173 
00174         /**
00175         * Return a Handle to the referenced Object.
00176         *
00177         * @return a Handle to the referenced Object
00178         */
00179         operator ValueHandle()
00180             {
00181             return getFinal();
00182             }
00183 
00184         /**
00185         * Return a View to the referenced Object.
00186         *
00187         * @return a View to the referenced Object
00188         */
00189         template<class PT>
00190         operator TypedHandle<const PT>() const
00191             {
00192             return getFinal();
00193             }
00194 
00195         /**
00196         * Return a Handle to the referenced Object.
00197         *
00198         * @return a Handle to the referenced Object
00199         */
00200         template<class PT>
00201         operator TypedHandle<PT>()
00202             {
00203             return getFinal();
00204             }
00205 
00206         /**
00207         * Return a TypedHolder to the referenced Object.
00208         *
00209         * @return a TypedHolder to the referenced Object
00210         *
00211         */
00212         template<class PT>
00213         operator TypedHolder<PT>() const
00214             {
00215             return getFinal();
00216             }
00217 
00218         /**
00219         * Return a TypedHolder to the referenced Object.
00220         *
00221         * @return a TypedHolder to the referenced Object
00222         */
00223         template<class PT>
00224         operator TypedHolder<PT>()
00225             {
00226             return getFinal();
00227             }
00228 
00229         /**
00230         * Dereference the FinalHandle.
00231         *
00232         * @return a const pointer to the referenced Object
00233         */
00234         const T* operator->() const
00235             {
00236             const T* cpo = MemberHandle<T>::m_po;
00237             if (MemberHandle<T>::m_nMutability < MemberHandle<T>::safe_immutable)
00238                 {
00239                 MemberHandle<T>::readBarrier();
00240                 if (cpo == NULL)
00241                     {
00242                     cpo = MemberHandle<T>::m_po;
00243                     MemberHandle<T>::readBarrier();
00244                     }
00245                 }
00246 
00247             if (NULL == cpo)
00248                 {
00249                 coh_throw_npe(typeid(const T));
00250                 }
00251             return cpo;
00252             }
00253 
00254         /**
00255         * Dereference the FinalHandle.
00256         *
00257         * @return a const pointer to the referenced Object
00258         */
00259         T* operator->()
00260             {
00261             T* po = MemberHandle<T>::m_po;
00262             if (po == NULL &&
00263                 MemberHandle<T>::m_nMutability < MemberHandle<T>::safe_immutable)
00264                 {
00265                 MemberHandle<T>::readBarrier();
00266                 po = MemberHandle<T>::m_po;
00267                 }
00268             if (MemberHandle<T>::m_fView)
00269                 {
00270                 coh_throw_illegal_state(
00271                     "attempt to access handle from const FinalHandle");
00272                 }
00273 
00274             if (NULL == po)
00275                 {
00276                 coh_throw_npe(typeid(T));
00277                 }
00278             return po;
00279             }
00280 
00281     private:
00282         /**
00283         * Blocked assignment operator.
00284         */
00285         FinalHandle& operator=(const ValueHandle& that);
00286 
00287         /**
00288         * Blocked assignment operator.
00289         */
00290         FinalHandle& operator=(const FinalHandle<T>& that);
00291 
00292         /**
00293         * Blocked assignment operator.
00294         */
00295         FinalHandle& operator=(FinalHandle<T>& that);
00296 
00297     // ----- SmartMember interface ------------------------------------------
00298 
00299     protected:
00300         /**
00301         * {@inheritDoc}
00302         */
00303         virtual size64_t retained() const
00304             {
00305             const T* cpo = MemberHandle<T>::m_po;
00306             if (cpo == NULL &&
00307                 MemberHandle<T>::m_nMutability < MemberHandle<T>::safe_immutable)
00308                 {
00309                 MemberHandle<T>::readBarrier();
00310                 cpo = MemberHandle<T>::m_po;
00311                 }
00312 
00313             return cpo == NULL
00314                     ? 0
00315                     : cpo->sizeOf(/*fDeep*/ true);
00316             }
00317 
00318 
00319     // ----- helper methods -------------------------------------------------
00320 
00321     protected:
00322         ValueView getFinal() const
00323             {
00324             const T* cpo = MemberHandle<T>::m_po;
00325             if (MemberHandle<T>::m_prev == NULL)
00326                 {
00327                 if (cpo == NULL &&
00328                     MemberHandle<T>::m_nMutability < MemberHandle<T>::safe_immutable)
00329                     {
00330                     MemberHandle<T>::readBarrier();
00331                     cpo = MemberHandle<T>::m_po;
00332                     }
00333                 return ValueView(cpo);
00334                 }
00335             else
00336                 {
00337                 return TypedHandle<const T>(cpo, *this);
00338                 }
00339             }
00340 
00341         ValueHandle getFinal()
00342             {
00343             T* po = MemberHandle<T>::m_po;
00344             if (MemberHandle<T>::m_fView)
00345                 {
00346                 coh_throw_illegal_state(
00347                     "attempt to access handle from const FinalHandle");
00348                 }
00349 
00350             if (MemberHandle<T>::m_prev == NULL)
00351                 {
00352                 if (po == NULL &&
00353                     MemberHandle<T>::m_nMutability < MemberHandle<T>::safe_immutable)
00354                     {
00355                     MemberHandle<T>::readBarrier();
00356                     }
00357                 return ValueHandle(po);
00358                 }
00359             else
00360                 {
00361                 return TypedHandle<T>(po, *this);
00362                 }
00363             }
00364 
00365 
00366         /**
00367         * Initialize the value of a FinalHandle after it is
00368         * constructed.  A FinalHandle may be initialized only if the
00369         * following conditions hold:
00370         * <ul>
00371         *   <li> The FinalHandle has not already been initialized
00372         *   (either during construction, or via <tt>initialize()</tt>)
00373         *   <li> The FinalHandle has not escaped
00374         * </ul>
00375         *
00376         * @param that  the value to initialize this FinalHandle to
00377         */
00378         void initialize(ValueHandle that)
00379             {
00380             if (MemberHandle<T>::m_nMutability >= MemberHandle<T>::forever_immutable)
00381                 {
00382                 coh_throw_illegal_state(
00383                     "attempt to initialize const FinalHandle");
00384                 }
00385             else if (MemberHandle<T>::m_prev == NULL)
00386                 {
00387                 SynchronizedMemberWriteBlock block(MemberHandle<T>::getGuardian());
00388                 if (MemberHandle<T>::m_po != NULL)
00389                     {
00390                     coh_throw_illegal_state(
00391                         "attempt to multiply initialize FinalHandle");
00392                     }
00393                 MemberHandle<T>::setEscaped(that, &block);
00394                 }
00395             else if (MemberHandle<T>::m_po != NULL)
00396                 {
00397                 coh_throw_illegal_state(
00398                     "attempt to multiply initialize FinalHandle");
00399                 }
00400             else if (that != NULL)
00401                 {
00402                 T* po = get_pointer(that);
00403                 MemberHandle<T>::m_po =
00404                     NULL == po || NULL == po->_attach(/*fEscaped*/ false)
00405                         ? NULL : po;
00406                 if (MemberHandle<T>::m_nMutability != MemberHandle<T>::forever_mutable)
00407                     {
00408                     MemberHandle<T>::m_nMutability = MemberHandle<T>::safe_immutable;
00409                     }
00410                 }
00411             }
00412 
00413     // ----- friends --------------------------------------------------------
00414 
00415     /**
00416     * @internal
00417     */
00418     template<class _T, class H> friend void initialize(FinalHandle<_T>& fh,
00419                                               H that);
00420     };
00421 
00422 /**
00423 * Perform a dynamic cast the pointer associated with the FinalHandle
00424 * to a the specified handle/view type.
00425 *
00426 * @param h       the FinalHandle from which to perform the cast
00427 * @param fThrow  true if an exception is to be thrown on a failed cast
00428 *
00429 * @return the casted pointer, or NULL if the cast fails and fThrow is false
00430 *
00431 * @throws ClassCastException if the cast fails and fThrow is true
00432 */
00433 template<class D, class T>
00434 D cast(FinalHandle<T>& h, bool fThrow = true)
00435     {
00436     return cast<D>((typename FinalHandle<T>::ValueHandle) h, fThrow);
00437     }
00438 
00439 /**
00440 * Perform a dynamic cast the pointer associated with the FinalHandle
00441 * to a the specified handle/view type.
00442 *
00443 * @param h       the FinalHandle from which to perform the cast
00444 * @param fThrow  true if an exception is to be thrown on a failed cast
00445 *
00446 * @return the casted pointer, or NULL if the cast fails and fThrow is false
00447 *
00448 * @throws ClassCastException if the cast fails and fThrow is true
00449 */
00450 template<class D, class T>
00451 D cast(const FinalHandle<T>& h, bool fThrow = true)
00452     {
00453     return cast<D>((typename FinalHandle<T>::ValueView) h, fThrow);
00454     }
00455 
00456 /**
00457 * Perform an instanceof check on a FinalHandle.
00458 *
00459 * @param h   the FinalHandle from which to perform the test
00460 *
00461 * @return true if the supplied handle is an instance of the specified type
00462 */
00463 template<class D, class T>
00464 bool instanceof(FinalHandle<T>& h)
00465     {
00466     return NULL != cast<D>(h, false);
00467     }
00468 
00469 /**
00470 * Perform an instanceof check on a FinalHandle.
00471 *
00472 * @param h   the FinalHandle from which to perform the test
00473 *
00474 * @return true if the supplied handle is an instance of the specified type
00475 */
00476 template<class D, class T>
00477 bool instanceof(const FinalHandle<T>& h)
00478     {
00479     return NULL != cast<D>(h, false);
00480     }
00481 
00482 /**
00483 * Initialize the value of a FinalHandle after it is constructed.  A
00484 * FinalHandle may be initialized only if the following conditions
00485 * hold:
00486 * <ul>
00487 *   <li> The FinalHandle has not already been initialized to a
00488 *   non-NULL value (either during construction, or via
00489 *   <tt>initialize()</tt>)
00490 * </ul>
00491 *
00492 * @param h     the FinalHandle to initialize
00493 * @param that  the value to initialize this FinalHandle to
00494 */
00495 template<class T, class H>
00496 void initialize(FinalHandle<T>& h, H that)
00497     {
00498     h.initialize(that);
00499     }
00500 
00501 COH_CLOSE_NAMESPACE2
00502 
00503 #endif // COH_FINAL_HANDLE_HPP
Copyright © 2000, 2013, Oracle and/or its affiliates. All rights reserved.