coherence/lang/MemberView.hpp

00001 /*
00002 * MemberView.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_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
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), m_cpo(NULL)
00078             {
00079             }
00080 
00081         /**
00082         * Construct a new MemberView referencing specified Object.
00083         *
00084         * @param oGuardian  the object that protects this member
00085         * @param that       the object to reference
00086         */
00087         MemberView(const Object& oGuardian, const ValueView& that)
00088             : SmartMember(oGuardian), m_cpo(NULL)
00089             {
00090             const T* cpo = get_pointer(that);
00091             if (cpo != NULL)
00092                 {
00093                 cpo->_attach(oGuardian._isEscaped());
00094                 m_cpo = cpo;
00095                 }
00096             }
00097 
00098         /**
00099         * Construct a new MemberView referencing specified Object.
00100         *
00101         * @param oGuardian  the object that protects this member
00102         * @param that       the object to reference
00103         * @param fMutable   true if the object was declared as mutable
00104         */
00105         MemberView(const Object& oGuardian, const ValueView& that, bool fMutable)
00106             : SmartMember(oGuardian, fMutable ? MUTABLE : SAFE_CONST),
00107               m_cpo(NULL)
00108             {
00109             const T* cpo = get_pointer(that);
00110             if (cpo != NULL)
00111                 {
00112                 cpo->_attach(oGuardian._isEscaped());
00113                 m_cpo = cpo;
00114                 }
00115             }
00116 
00117         /**
00118         * Destroy the MemberView.
00119         */
00120         ~MemberView()
00121             {
00122             const T* cpo = m_cpo;
00123             if (cpo != NULL)
00124                 {
00125                 m_cpo = NULL;
00126                 try
00127                     {
00128                     cpo->_detach(getGuardian()._isEscaped());
00129                     }
00130                 catch (const std::exception& e)
00131                     {
00132                     // Exception::View is not a known type within this file
00133                     std::cerr << "Error during ~MemberView: " << e.what()
00134                         << std::endl;
00135                     return; // can't re-throw from within destructor
00136                     }
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 != NULL)
00240                 {
00241                 cpo->_attach(fEscaped);  // new attach
00242                 cpo->_detach(!fEscaped); // old detach
00243                 }
00244 
00245             SmartMember::onEscape(fEscaped);
00246             }
00247 
00248 
00249     // ----- helper methods -------------------------------------------------
00250 
00251     protected:
00252         /**
00253         * Set the view to reference an Object via a View.
00254         *
00255         * @param that   the Object to reference
00256         * @param pSync  optional external SyncornizedMemberWriteBlock to use
00257         *               to avoid internal synchronization.
00258         */
00259         void set(const TypedHolder<T>& that,
00260                  SynchronizedMemberWriteBlock* pSync = NULL)
00261             {
00262             const Object& oGuardian = getGuardian();
00263             const T*      cpDetach  = NULL;
00264             const T*      cpo       = get_pointer(that);
00265             bool          fEscaped  = oGuardian._isEscaped();
00266             const Object* cpAttach  = NULL == cpo ? NULL : cpo->_attach(fEscaped);
00267 
00268             if (pSync != NULL)
00269                 {
00270                 // sync block
00271                 SynchronizedMemberWriteBlock syncWrite(oGuardian, pSync);
00272                 if (m_nMutability >= CONST)
00273                     {
00274                     coh_throw_illegal_state("attempt to set const MemberView");
00275                     }
00276 
00277                 cpDetach = m_cpo;
00278                 m_cpo    = NULL == cpAttach ? NULL : cpo;
00279                 }
00280             else if (fEscaped)
00281                 {
00282                 // sync block
00283                 SynchronizedMemberWriteBlock::Guard guard(oGuardian);
00284                 if (m_nMutability >= CONST)
00285                     {
00286                     coh_throw_illegal_state("attempt to set const MemberView");
00287                     }
00288 
00289                 cpDetach = m_cpo;
00290                 m_cpo    = NULL == cpAttach ? NULL : cpo;
00291                 }
00292             else
00293                 {
00294                 if (m_nMutability >= CONST)
00295                     {
00296                     coh_throw_illegal_state("attempt to set const MemberView");
00297                     }
00298 
00299                 cpDetach = m_cpo;
00300                 m_cpo    = NULL == cpAttach ? NULL : cpo;
00301                 }
00302 
00303             if (cpDetach)
00304                 {
00305                 cpDetach->_detach(fEscaped);
00306                 }
00307             }
00308 
00309         /**
00310         * Return a View to the referenced Object.
00311         *
00312         * @param pSync  optional external SyncornizedMemberReadBlock to use
00313         *               to avoid internal synchronization.
00314         *
00315         * @return a View to the referenced Object
00316         */
00317         ValueView get(SynchronizedMemberReadBlock* pSync = NULL) const
00318             {
00319             const Object& oGuardian = getGuardian();
00320 
00321             if (pSync != NULL)
00322                 {
00323                 // sync block
00324                 SynchronizedMemberReadBlock syncRead(oGuardian, pSync);
00325                 return ValueView(m_cpo); // must occur within scope of syncRead
00326                 }
00327             else if (m_nMutability == SAFE_CONST || !oGuardian._isEscaped())
00328                 {
00329                 // non-escaped, or SAFE_CONST, synchronization not required
00330                 return ValueView(m_cpo);
00331                 }
00332             else
00333                 {
00334                 // sync block
00335                 SynchronizedMemberReadBlock::Guard guard(oGuardian);
00336                 return ValueView(m_cpo); // must occur within scope of guard
00337                 }
00338             }
00339 
00340 
00341     // ----- data members ---------------------------------------------------
00342 
00343     protected:
00344         /**
00345         * The referenced Object.
00346         */
00347         const T* m_cpo;
00348 
00349 
00350     // ----- friends --------------------------------------------------------
00351 
00352     /**
00353     * @internal
00354     */
00355     friend class SynchronizedMemberReadBlock;
00356 
00357     /**
00358     * @internal
00359     */
00360     friend class SynchronizedMemberWriteBlock;
00361     };
00362 
00363 
00364 // ----- non-member operators and functions ---------------------------------
00365 
00366 /**
00367 * Output a human-readable description of the given MemberView to the
00368 * specified stream.
00369 *
00370 * @param out  the stream used to output the description
00371 * @param mv   the MemberView to describe
00372 *
00373 * @return the supplied stream
00374 */
00375 template<class T> std::ostream& operator<<(std::ostream& out, const MemberView<T>& mv)
00376     {
00377     out << (typename T::View) mv;
00378     return out;
00379     }
00380 
00381 /**
00382 * Assign the specified holder to NULL.
00383 *
00384 * @param mv the MemberView to clear
00385 */
00386 template<class T> void clear_handle(MemberView<T>& mv)
00387     {
00388     mv = NULL;
00389     }
00390 
00391 /**
00392 * Perform a dynamic cast the pointer associated with the MemberView
00393 * to a the specified handle/view type.
00394 *
00395 * @param mv      the MemberView from which to perform the cast
00396 * @param fThrow  true if an exception is to be thrown on a failed cast
00397 *
00398 * @return the casted pointer, or NULL if the cast fails and fThrow is false
00399 *
00400 * @throws ClassCastException if the cast fails and fThrow is true
00401 */
00402 template<class D, class T>
00403 D cast(const MemberView<T>& mv, bool fThrow = true)
00404     {
00405     return cast<D>((typename MemberView<T>::ValueView) mv, fThrow);
00406     }
00407 
00408 /**
00409 * Perform an instanceof check on a MemberView.
00410 *
00411 * @param mv  the MemberView from which to perform the test
00412 *
00413 * @return true if the supplied handle is an instance of the specified type
00414 */
00415 template<class D, class T>
00416 bool instanceof(const MemberView<T>& mv)
00417     {
00418     return NULL != cast<D>(mv, false);
00419     }
00420 
00421 /**
00422 * Return true if the supplied holder equals NULL.
00423 *
00424 * @param mv  the MemberView to test
00425 *
00426 * @return true iff the supplied MemberView equals NULL
00427 */
00428 template<class T>
00429 bool is_null(const MemberView<T>& mv)
00430     {
00431     return mv == NULL;
00432     }
00433 
00434 COH_CLOSE_NAMESPACE2
00435 
00436 #endif // COH_MEMBER_VIEW_HPP
Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.