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

E77779-01

coherence/lang/MemberView.hpp

00001 /*
00002 * MemberView.hpp
00003 *
00004 * Copyright (c) 2000, 2016, 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_MEMBER_VIEW_HPP
00017 #define COH_MEMBER_VIEW_HPP
00018 
00019 #include "coherence/lang/compatibility.hpp"
00020 
00021 #include "coherence/lang/Object.hpp"
00022 #include "coherence/lang/SmartMember.hpp"
00023 #include "coherence/lang/SynchronizedMemberReadBlock.hpp"
00024 #include "coherence/lang/SynchronizedMemberWriteBlock.hpp"
00025 #include "coherence/lang/TypedHandle.hpp"
00026 #include "coherence/lang/TypedHolder.hpp"
00027 
00028 #include <ostream>
00029 
00030 COH_OPEN_NAMESPACE2(coherence,lang)
00031 
00032 /**
00033 * MemberView is a thread-safe view intended for use as a data-member within
00034 * Objects.
00035 *
00036 * Note: In the rare case that a MemberView is declared via the mutable
00037 *       keyword, the MemberView must be informed of this fact by setting
00038 *       fMutable to true during construction.
00039 *
00040 * @author mf  2008.01.09
00041 *
00042 * @see MemberHandle
00043 * @see MemberHolder
00044 */
00045 template<class T>
00046 class MemberView
00047     : public SmartMember, public ChainedHandleElement
00048     {
00049     // ----- typedefs -------------------------------------------------------
00050 
00051     public:
00052         /**
00053         * The type of the values the holder can reference.
00054         */
00055         typedef T ValueType;
00056 
00057         /**
00058         * The View type for the referenced Object.
00059         */
00060         typedef typename T::View ValueView;
00061 
00062         /**
00063         * Result type for a non-const get operation.
00064         */
00065         typedef ValueView GetType;
00066 
00067 
00068     // -------- constructors ------------------------------------------------
00069 
00070     public:
00071         /**
00072         * Construct a new MemberView referencing NULL via a handle.
00073         *
00074         * @param oGuardian  the object that protects this member
00075         */
00076         MemberView(const Object& oGuardian)
00077             : SmartMember(oGuardian), ChainedHandleElement(/*fView*/ true),
00078               m_cpo(NULL)
00079             {
00080             if (oGuardian._isEscaped())
00081                 {
00082                 m_prev = m_next = NULL;
00083                 }
00084             }
00085 
00086         /**
00087         * Construct a new MemberView referencing specified Object.
00088         *
00089         * @param oGuardian  the object that protects this member
00090         * @param that       the object to reference
00091         */
00092         MemberView(const Object& oGuardian, const ValueView& that)
00093             : SmartMember(oGuardian),  ChainedHandleElement(/*fView*/ true),
00094               m_cpo(NULL)
00095             {
00096             if (oGuardian._isEscaped())
00097                 {
00098                 m_prev = m_next = NULL;
00099                 }
00100             set(that);
00101             }
00102 
00103         /**
00104         * Construct a new MemberView referencing specified Object.
00105         *
00106         * @param oGuardian  the object that protects this member
00107         * @param that       the object to reference
00108         * @param fMutable   true if the object was declared as mutable
00109         */
00110         MemberView(const Object& oGuardian, const ValueView& that, bool fMutable)
00111             : SmartMember(oGuardian), ChainedHandleElement(/*fView*/ true),
00112               m_cpo(NULL)
00113             {
00114             if (oGuardian._isEscaped())
00115                 {
00116                 m_prev = m_next = NULL;
00117                 }
00118             set(that);
00119             m_nMutability = fMutable ? forever_mutable : safe_immutable;
00120             }
00121 
00122         /**
00123         * Destroy the MemberView.
00124         */
00125         ~MemberView()
00126             {
00127             try
00128                 {
00129                 m_nMutability = inherited;
00130                 set(NULL);
00131                 }
00132             catch (const std::exception& e)
00133                 {
00134                 // Exception::View is not a known type within this file
00135                 std::cerr << "Error during ~MemberView: " << e.what() << std::endl;
00136                 return; // can't re-throw from within destructor
00137                 }
00138             }
00139 
00140     private:
00141         /**
00142         * Blocked copy constructor.
00143         */
00144         MemberView(const MemberView&);
00145 
00146 
00147     // ----- operators ------------------------------------------------------
00148 
00149     public:
00150         /**
00151         * Assign the MemberView to reference another object.
00152         *
00153         * @param that  the object to reference
00154         *
00155         * @return a reference to this MemberView
00156         */
00157         MemberView& operator=(const ValueView& that)
00158             {
00159             set(that);
00160             return *this;
00161             }
00162 
00163         /**
00164         * Assign the MemberView to reference another object.
00165         *
00166         * @param that  the object to reference
00167         *
00168         * @return a reference to this MemberView
00169         */
00170         MemberView& operator=(const MemberView& that)
00171             {
00172             set(that);
00173             return *this;
00174             }
00175 
00176         /**
00177         * Return a View to the referenced Object.
00178         *
00179         * @return a View to the referenced Object
00180         */
00181         operator ValueView() const
00182             {
00183             return get();
00184             }
00185 
00186         /**
00187         * Return a View to the referenced Object.
00188         *
00189         * @return a View to the referenced Object
00190         */
00191         template<class PT>
00192         operator TypedHandle<const PT>() const
00193             {
00194             return get();
00195             }
00196 
00197         /**
00198         * Return a TypedHolder to the referenced Object.
00199         *
00200         * @return a TypedHolder to the referenced Object
00201         */
00202         template<class PT>
00203         operator TypedHolder<PT>() const
00204             {
00205             return get();
00206             }
00207 
00208         /**
00209         * Dereference the MemberView.
00210         *
00211         * @return a const pointer to the referenced Object
00212         */
00213         ValueView operator->() const
00214             {
00215             return get();
00216             }
00217 
00218         /**
00219         * Dereference this handle, returning <tt>T&</tt>.
00220         *
00221         * @return a raw <tt>T&</tt> reference to the referenced Object
00222         *
00223         * @throws NullPointerException if the this handle is @c NULL
00224         */
00225         const T& operator*() const
00226             {
00227             return *get();
00228             }
00229 
00230     // ----- SmartMember interface ------------------------------------------
00231 
00232     protected:
00233         /**
00234         * {@inheritDoc}
00235         */
00236         virtual void onEscape(bool fEscaped) const
00237             {
00238             const T* cpo = m_cpo;
00239             if (cpo)
00240                 {
00241                 cpo->_attach(fEscaped);
00242                 }
00243 
00244             if (fEscaped)
00245                 {
00246                 performAction(unlink());
00247                 m_prev = m_next = NULL;
00248                 }
00249             else
00250                 {
00251                 if (cpo)
00252                     {
00253                     cpo->_detach(/*fEscaped*/ true);
00254                     }
00255                 m_prev = m_next = this;
00256                 }
00257 
00258             SmartMember::onEscape(fEscaped);
00259             }
00260 
00261         /**
00262         * {@inheritDoc}
00263         */
00264         virtual size64_t retained() const
00265             {
00266             ValueView v = get();
00267             return v == NULL
00268                     ? 0
00269                     : v->sizeOf(/*fDeep*/ true);
00270             }
00271 
00272 
00273     // ----- helper methods -------------------------------------------------
00274 
00275     protected:
00276         /**
00277         * Set the view to reference an Object via a View.
00278         *
00279         * @param that   the Object to reference
00280         * @param pSync  optional external SyncornizedMemberWriteBlock to use
00281         *               to avoid internal synchronization.
00282         */
00283         void set(const TypedHolder<T>& that,
00284                  SynchronizedMemberWriteBlock* pSync = NULL)
00285             {
00286             if (m_prev == NULL)
00287                 {
00288                 setEscaped(that, pSync);
00289                 }
00290             else if (m_nMutability >= forever_immutable)
00291                 {
00292                 coh_throw_illegal_state("attempt to set const MemberView");
00293                 }
00294             else
00295                 {
00296                 performAction(link(that));
00297                 m_cpo = get_pointer(that);
00298                 }
00299             }
00300 
00301         /**
00302         * Set the escaped view to reference an Object via a View.
00303         *
00304         * @param that   the Object to reference
00305         * @param pSync  optional external SyncornizedMemberWriteBlock to use
00306         *               to avoid internal synchronization.
00307         */
00308         void setEscaped(const TypedHolder<T>& that,
00309                  SynchronizedMemberWriteBlock* pSync = NULL)
00310             {
00311             const Object& oGuardian = getGuardian();
00312             const T*      cpo       = get_pointer(that);
00313             const T*      cpDetach  = NULL;
00314             const Object* cpAttach  = NULL == cpo ? NULL : cpo->_attach(/*fEscaped*/ true);
00315 
00316             if (pSync == NULL)
00317                 {
00318                 // sync block
00319                 SynchronizedMemberWriteBlock::Guard guard(oGuardian);
00320                 if (m_nMutability >= forever_immutable)
00321                     {
00322                     coh_throw_illegal_state("attempt to set const MemberView");
00323                     }
00324 
00325                 cpDetach = m_cpo;
00326                 m_cpo    = NULL == cpAttach ? NULL : cpo;
00327                 }
00328             else
00329                 {
00330                 // sync block
00331                 SynchronizedMemberWriteBlock syncWrite(oGuardian, pSync);
00332                 if (m_nMutability >= forever_immutable)
00333                     {
00334                     coh_throw_illegal_state("attempt to set const MemberView");
00335                     }
00336 
00337                 cpDetach = m_cpo;
00338                 m_cpo    = NULL == cpAttach ? NULL : cpo;
00339                 }
00340 
00341             if (cpDetach)
00342                 {
00343                 cpDetach->_detach(/*fEscaped*/ true);
00344                 }
00345 
00346             }
00347 
00348         /**
00349         * Return a View to the referenced Object.
00350         *
00351         * @param pSync  optional external SyncornizedMemberReadBlock to use
00352         *               to avoid internal synchronization.
00353         *
00354         * @return a View to the referenced Object
00355         */
00356         ValueView get(SynchronizedMemberReadBlock* pSync = NULL) const
00357             {
00358             if (m_prev == NULL)
00359                 {
00360                 return getEscaped(pSync);
00361                 }
00362             else
00363                 {
00364                 return TypedHandle<const T>(m_cpo, *this);
00365                 }
00366             }
00367 
00368         /**
00369         * Return a View to the referenced Object.
00370         *
00371         * @param pSync  optional external SyncornizedMemberReadBlock to use
00372         *               to avoid internal synchronization.
00373         *
00374         * @return a View to the referenced Object
00375         */
00376         ValueView getEscaped(SynchronizedMemberReadBlock* pSync = NULL) const
00377             {
00378             const Object& oGuardian = getGuardian();
00379             if (pSync != NULL)
00380                 {
00381                 // sync block
00382                 SynchronizedMemberReadBlock syncRead(oGuardian, pSync);
00383                 return ValueView(m_cpo); // must occur within scope of syncRead
00384                 }
00385             else if (m_nMutability == safe_immutable)
00386                 {
00387                 // safe_immutable, synchronization not required
00388                 return ValueView(m_cpo);
00389                 }
00390             else
00391                 {
00392                 // sync block
00393                 SynchronizedMemberReadBlock::Guard guard(oGuardian);
00394                 return ValueView(m_cpo); // must occur within scope of guard
00395                 }
00396             }
00397 
00398 
00399 
00400         /**
00401         * Perform the specified action.
00402         *
00403         * @param nAction  the action to perform
00404         */
00405         void performAction(Action nAction) const
00406             {
00407             const T* cpo = m_cpo;
00408             switch (nAction)
00409                 {
00410                 case action_error:
00411                 case action_flip:
00412                     coh_throw_illegal_state("corrupted ChainedHandleElement");
00413                 case action_detach:
00414                     if (cpo) cpo->_detach(/*fEscaped*/ false);
00415                     // fall through
00416                 case action_none:
00417                 default:
00418                     break;
00419                 }
00420             }
00421 
00422 
00423     // ----- data members ---------------------------------------------------
00424 
00425     protected:
00426         /**
00427         * The referenced Object.
00428         */
00429         const T* m_cpo;
00430 
00431     // ----- friends --------------------------------------------------------
00432 
00433     /**
00434     * @internal
00435     */
00436     friend class SynchronizedMemberReadBlock;
00437 
00438     /**
00439     * @internal
00440     */
00441     friend class SynchronizedMemberWriteBlock;
00442     };
00443 
00444 
00445 // ----- non-member operators and functions ---------------------------------
00446 
00447 /**
00448 * Output a human-readable description of the given MemberView to the
00449 * specified stream.
00450 *
00451 * @param out  the stream used to output the description
00452 * @param mv   the MemberView to describe
00453 *
00454 * @return the supplied stream
00455 */
00456 template <typename Char, typename Traits, class T>
00457 COH_INLINE std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& out, const MemberView<T>& mv)
00458     {
00459     out << (typename T::View) mv;
00460     return out;
00461     }
00462 
00463 /**
00464 * Assign the specified holder to NULL.
00465 *
00466 * @param mv the MemberView to clear
00467 */
00468 template<class T> void clear_handle(MemberView<T>& mv)
00469     {
00470     mv = NULL;
00471     }
00472 
00473 /**
00474 * Perform a dynamic cast the pointer associated with the MemberView
00475 * to a the specified handle/view type.
00476 *
00477 * @param mv      the MemberView from which to perform the cast
00478 * @param fThrow  true if an exception is to be thrown on a failed cast
00479 *
00480 * @return the casted pointer, or NULL if the cast fails and fThrow is false
00481 *
00482 * @throws ClassCastException if the cast fails and fThrow is true
00483 */
00484 template<class D, class T>
00485 D cast(const MemberView<T>& mv, bool fThrow = true)
00486     {
00487     return cast<D>((typename MemberView<T>::ValueView) mv, fThrow);
00488     }
00489 
00490 /**
00491 * Perform an instanceof check on a MemberView.
00492 *
00493 * @param mv  the MemberView from which to perform the test
00494 *
00495 * @return true if the supplied handle is an instance of the specified type
00496 */
00497 template<class D, class T>
00498 bool instanceof(const MemberView<T>& mv)
00499     {
00500     return NULL != cast<D>(mv, false);
00501     }
00502 
00503 /**
00504 * Return true if the supplied holder equals NULL.
00505 *
00506 * @param mv  the MemberView to test
00507 *
00508 * @return true iff the supplied MemberView equals NULL
00509 */
00510 template<class T>
00511 bool is_null(const MemberView<T>& mv)
00512     {
00513     return mv == NULL;
00514     }
00515 
00516 COH_CLOSE_NAMESPACE2
00517 
00518 #endif // COH_MEMBER_VIEW_HPP
Copyright © 2000, 2016, Oracle and/or its affiliates. All rights reserved.