Oracle Coherence for C++ API
Release 3.6.0.0
E15728-01

- Main Page
- Namespaces
- Classes
- Files

# coherence/lang/MemberView.hpp

    00001 /*
    00002 * MemberView.hpp
    00003 *
    00004 * Copyright (c) 2000, 2010, 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 © 2000, 2010, Oracle and/or its affiliates. All rights reserved.