coherence/lang/MemberView.hpp

00001 /*
00002 * MemberView.hpp
00003 *
00004 * Copyright 2001-2008 by Oracle. 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/IllegalStateException.hpp"
00022 #include "coherence/lang/MemberHandle.hpp"
00023 #include "coherence/lang/Object.hpp"
00024 #include "coherence/lang/SmartMember.hpp"
00025 #include "coherence/lang/SynchronizedMemberReadBlock.hpp"
00026 #include "coherence/lang/SynchronizedMemberWriteBlock.hpp"
00027 #include "coherence/lang/TypedHandle.hpp"
00028 #include "coherence/lang/TypedHolder.hpp"
00029 
00030 #include <ostream>
00031 
00032 COH_OPEN_NAMESPACE2(coherence,lang)
00033 
00034 class Object;
00035 
00036 
00037 /**
00038 * MemberView is a thread-safe view intended for use as a data-member within
00039 * Objects.
00040 *
00041 * @author mf  2008.01.09
00042 *
00043 * @see MemberHandle
00044 * @see MemberHolder
00045 */
00046 template<class T>
00047 class MemberView
00048         : public SmartMember
00049     {
00050     // ----- typedefs -------------------------------------------------------
00051 
00052     public:
00053         /**
00054         * The type of the values the holder can reference.
00055         */
00056         typedef T ValueType;
00057 
00058         /**
00059         * The View type for the referenced Object.
00060         */
00061         typedef typename T::View ValueView;
00062 
00063         /**
00064         * Result type for a non-const get operation.
00065         */
00066         typedef ValueView GetType;
00067 
00068 
00069     // -------- constructors ------------------------------------------------
00070 
00071     public:
00072         /**
00073         * Construct a new MemberView referencing NULL via a handle.
00074         *
00075         * @param oParent  the self() on the object this data member is a
00076         *                 member of
00077         */
00078         MemberView(Object& oParent)
00079                 : SmartMember(oParent), m_cpo(NULL)
00080             {
00081             }
00082 
00083         /**
00084         * Construct a new MemberView refrencing specified Object via a View.
00085         *
00086         * @param oParent  the self() on the object this data member is a
00087         *                 member of
00088         * @param h        a handle to the Object to reference
00089         */
00090         template<class DT> MemberView(Object& oParent, const TypedHandle<DT>& h)
00091                 : SmartMember(oParent), m_cpo(NULL)
00092             {
00093             set(h);
00094             }
00095 
00096         /**
00097         * Construct a new MemberView refrencing the same Object as the
00098         * specified TypedHolder.
00099         *
00100         * @param oParent  the self() on the object this data member is a
00101         *                 member of
00102         * @param th       the TypedHolder to initialize from
00103         */
00104         template<class DT> MemberView(Object& oParent, const TypedHolder<DT>& th)
00105                 : SmartMember(oParent), m_cpo(NULL)
00106             {
00107             operator=(th);
00108             }
00109 
00110         /**
00111         * Construct a new MemberView refrencing the same Object as the
00112         * specified MemberHolder.
00113         *
00114         * @param oParent  the self() on the object this data member is a
00115         *                 member of
00116         * @param mh       the MemberHolder to initialize from
00117         */
00118         template<class DT> MemberView(Object& oParent, const MemberHolder<DT>& mh)
00119                 : SmartMember(oParent), m_cpo(NULL)
00120             {
00121             operator=(mh);
00122             }
00123 
00124         /**
00125         * Construct a new MemberView refrencing the same Object as the
00126         * specified MemberView.
00127         *
00128         * @param oParent  the self() on the object this data member is a
00129         *                 member of
00130         * @param that     the MemberView to initialize from
00131         */
00132         template<class DT> MemberView(Object& oParent, const MemberView<DT>& that)
00133                 : SmartMember(oParent), m_cpo(NULL)
00134             {
00135             operator=(that);
00136             }
00137 
00138         /**
00139         * Construct a new MemberView refrencing the same Object as the
00140         * specified MemberView.
00141         *
00142         * @param oParent  the self() on the object this data member is a
00143         *                 member of
00144         * @param that     the MemberView to initialize from
00145         */
00146         template<class DT> MemberView(Object& oParent, const MemberHandle<DT>& that)
00147                 : SmartMember(oParent), m_cpo(NULL)
00148             {
00149             operator=(that);
00150             }
00151 
00152         /**
00153         * Destroy the MemberView.
00154         */
00155         ~MemberView()
00156             {
00157             set(ValueView());
00158             }
00159 
00160     private:
00161         /**
00162         * Blocked copy constructor.
00163         */
00164         MemberView(const MemberView&);
00165 
00166 
00167     // ----- operators ------------------------------------------------------
00168 
00169     public:
00170         /**
00171         * Assign this MemberView to refrence the same Object as the specified
00172         * MemberView.
00173         *
00174         * @param that  the MemberView to assign from
00175         *
00176         * @return a reference to this MemberView
00177         */
00178         MemberView& operator=(const MemberView& that)
00179             {
00180             operator=((ValueView) that); // assign from snapshot
00181             return *this;
00182             }
00183 
00184         /**
00185         * Assign this MemberView to refrence the same Object as the specified
00186         * MemberView.
00187         *
00188         * @param mv  the MemberView to assign from
00189         *
00190         * @return a reference to this MemberView
00191         */
00192         template<class DT> MemberView& operator=(const MemberView<DT>& mv)
00193             {
00194             operator=((TypedHandle<const DT>) mv);
00195             return *this;
00196             }
00197 
00198         /**
00199         * Assign this MemberView to refrence the same Object as the specified
00200         * MemberView.
00201         *
00202         * @param th  the TypedHolder to assign from
00203         *
00204         * @return a reference to this MemberView
00205         */
00206         template<class DT> MemberView& operator=(const TypedHolder<DT>& th)
00207             {
00208             set(th);
00209             return *this;
00210             }
00211 
00212         /**
00213         * Assign this MemberView to refrence the same Object as the specified
00214         * MemberHolder.
00215         *
00216         * @param mh  the MemberHolder to assign from
00217         *
00218         * @return a reference to this MemberView
00219         */
00220         template<class DT> MemberView& operator=(const MemberHolder<DT>& mh)
00221             {
00222             set(mh);
00223             return *this;
00224             }
00225 
00226         /**
00227         * Assign this MemberView to refrence the same Object as the specified
00228         * MemberHandle.
00229         *
00230         * @param mh  the MemberHandle to assign from
00231         *
00232         * @return a reference to this MemberView
00233         */
00234         template<class DT> MemberView& operator=(const MemberHandle<DT>& mh)
00235             {
00236             set((typename MemberHandle<DT>::ValueView) mh);
00237             return *this;
00238             }
00239 
00240         /**
00241         * Assign this MemberView to refrence the same Object (and in the
00242         * same manner) as the specified MemberView.
00243         *
00244         * @param h  the TypedHandle to assign from
00245         *
00246         * @return a reference to this MemberView
00247         */
00248         template<class DT> MemberView& operator=(const TypedHandle<DT>& h)
00249             {
00250             set(h);
00251             return *this;
00252             }
00253 
00254         /**
00255         * Assign this MemberView to refrence the same Object (and in the
00256         * same manner) as the specified pointer.
00257         *
00258         * @param cp  the pointer to assign from
00259         *
00260         * @return a reference to this MemberView
00261         */
00262         MemberView& operator=(const T* cp)
00263             {
00264             return operator=((ValueView) cp);
00265             }
00266 
00267         /**
00268         * Return a View to the referenced Object.
00269         *
00270         * @return a View to the referenced Object
00271         */
00272         operator ValueView() const
00273             {
00274             SynchronizedMemberReadBlock syncRead(getParent());
00275             return m_cpo;
00276             }
00277 
00278         /**
00279         * Return a View to the referenced Object.
00280         *
00281         * @return a View to the referenced Object
00282         */
00283         template<class PT>
00284         operator TypedHandle<const PT>() const
00285             {
00286             return (ValueView) *this;
00287             }
00288 
00289         /**
00290         * Return a TypedHolder to the referenced Object.
00291         *
00292         * @return a TypedHolder to the referenced Object
00293         */
00294         template<class PT>
00295         operator TypedHolder<PT>() const
00296             {
00297             return (ValueView) *this;
00298             }
00299 
00300         /**
00301         * Derefrence the MemberView.
00302         *
00303         * @return a const pointer to the referenced Object
00304         */
00305         ValueView operator->() const
00306             {
00307             return (ValueView) *this;
00308             }
00309 
00310         /**
00311         * Compare the supplied MemberView to this MemberView.
00312         *
00313         * @param mv  the MemberView to compare against
00314         *
00315         * @return true iff the same object is referenced
00316         */
00317         template<class AT>
00318         bool operator==(const MemberView<AT>& mv) const
00319             {
00320             typename MemberView<AT>::ValueView v = mv;
00321             return operator==(v);
00322             }
00323 
00324         /**
00325         * Compare the supplied MemberView to this view.
00326         *
00327         * @param mv  the holder to compare against
00328         *
00329         * @return true iff different objects are referenced
00330         */
00331         template<class AT>
00332         bool operator!=(const MemberView<AT>& mv) const
00333             {
00334             return !operator==(mv);
00335             }
00336 
00337         /**
00338         * Compare the supplied MemberHolder to this MemberView.
00339         *
00340         * @param mh  the MemberHolder to compare against
00341         *
00342         * @return true iff the same object is referenced
00343         */
00344         template<class AT>
00345         bool operator==(const MemberHolder<AT>& mh) const
00346             {
00347             typename TypedHolder<AT>::ValueView v = mh;
00348             return operator==(v);
00349             }
00350 
00351         /**
00352         * Compare the supplied MemberHolder to this MemberView.
00353         *
00354         * @param mh  the holder to compare against
00355         *
00356         * @return true iff different objects are referenced
00357         */
00358         template<class AT>
00359         bool operator!=(const MemberHolder<AT>& mh) const
00360             {
00361             return !operator==(mh);
00362             }
00363 
00364         /**
00365         * Compare the supplied MemberHandle to this MemberView.
00366         *
00367         * @param mh  the MemberHandle to compare against
00368         *
00369         * @return true iff the same object is referenced
00370         */
00371         template<class AT>
00372         bool operator==(const MemberHandle<AT>& mh) const
00373             {
00374             typename MemberHandle<AT>::ValueView v = mh;
00375             return operator==(v);
00376             }
00377 
00378         /**
00379         * Compare the supplied MemberHandle to this MemberView.
00380         *
00381         * @param mh  the handle to compare against
00382         *
00383         * @return true iff different objects are referenced
00384         */
00385         template<class AT>
00386         bool operator!=(const MemberHandle<AT>& mh) const
00387             {
00388             return !operator==(mh);
00389             }
00390 
00391         /**
00392         * Compare the supplied holder to this view.
00393         *
00394         * @param th  the holder to compare against
00395         *
00396         * @return true iff the same object is referenced
00397         */
00398         template<class AT>
00399         bool operator==(const TypedHolder<AT>& th) const
00400             {
00401             return operator==(get_pointer((typename TypedHolder<AT>::ValueView) th));
00402             }
00403 
00404         /**
00405         * Compare the supplied holder to this view.
00406         *
00407         * @param th  the holder to compare against
00408         *
00409         * @return true iff different objects are referenced
00410         */
00411         template<class AT>
00412         bool operator!=(const TypedHolder<AT>& th) const
00413             {
00414             return !operator==(th);
00415             }
00416 
00417         /**
00418         * Compare the supplied handle to this view.
00419         *
00420         * @param h  the handle to compare against
00421         *
00422         * @return true iff the same object is referenced
00423         */
00424         template<class AT>
00425         bool operator==(const TypedHandle<AT>& h) const
00426             {
00427             return operator==(get_pointer(h));
00428             }
00429 
00430         /**
00431         * Compare the supplied handle to this view.
00432         *
00433         * @param h  the handle to compare against
00434         *
00435         * @return true iff the different objects are referenced
00436         */
00437         template<class AT>
00438         bool operator!=(const TypedHandle<AT>& h) const
00439             {
00440             return !operator==(h);
00441             }
00442 
00443         /**
00444         * Compare the supplied pointer to this view.
00445         *
00446         * @param cpThat  the pointer to compare against
00447         *
00448         * @return true iff the same object is referenced
00449         */
00450         bool operator==(const Object* cpThat) const
00451             {
00452             SynchronizedMemberReadBlock syncRead(getParent());
00453             return ((const Object*) m_cpo) == cpThat;
00454             }
00455 
00456         /**
00457         * Compare the supplied pointer to this view.
00458         *
00459         * @param cpThat  the pointer to compare against
00460         *
00461         * @return true iff different objects are referenced
00462         */
00463         bool operator!=(const Object* cpThat) const
00464             {
00465             return !operator==(cpThat);
00466             }
00467 
00468 
00469     // ----- helper methods -------------------------------------------------
00470 
00471     protected:
00472         /**
00473         * Set the view to reference an Object via a View.
00474         *
00475         * @param v      the View to the Object to reference
00476         * @param pSync  optional external SyncornizedMemberWriteBlock to use
00477         *               to avoid internal synchronization.
00478         *
00479         */
00480         void set(ValueView v, SynchronizedMemberWriteBlock* pSync = NULL)
00481             {
00482             const T*      cpo      = get_pointer(v);
00483             const Object* cpAttach = NULL == cpo ? NULL : cpo->_attach();
00484             const T*      cpDetach = NULL;
00485 
00486             // sync block
00487                 {
00488                 SynchronizedMemberWriteBlock syncWrite(getParent(), pSync);
00489                 cpDetach = m_cpo;
00490                 m_cpo = NULL == cpAttach ? NULL : cpo;
00491                 }
00492 
00493             if (cpDetach)
00494                 {
00495                 cpDetach->_detach();
00496                 }
00497             }
00498 
00499         /**
00500         * Return a View to the referenced Object.
00501         *
00502         * @param pSync  optional external SyncornizedMemberReadBlock to use
00503         *               to avoid internal synchronization.
00504         *
00505         * @return a View to the referenced Object
00506         */
00507         ValueView get(SynchronizedMemberReadBlock* pSync = NULL) const
00508             {
00509             SynchronizedMemberReadBlock syncRead(getParent(), pSync);
00510             return m_cpo;
00511             }
00512 
00513 
00514     // ----- data members ---------------------------------------------------
00515 
00516     private:
00517         /**
00518         * The referenced Object.
00519         */
00520         const T* m_cpo;
00521 
00522 
00523     // ----- friends --------------------------------------------------------
00524 
00525     /**
00526     * @internal
00527     */
00528     friend class SynchronizedMemberReadBlock;
00529 
00530     /**
00531     * @internal
00532     */
00533     friend class SynchronizedMemberWriteBlock;
00534     };
00535 
00536 
00537 // ----- non-member operators and functions ---------------------------------
00538 
00539 /**
00540 * Output a human-readable description of the given MemberView to the
00541 * specified stream.
00542 *
00543 * @param out  the stream used to output the description
00544 * @param mv   the MemberView to describe
00545 *
00546 * @return the supplied stream
00547 */
00548 template<class T> std::ostream& operator<<(std::ostream& out, const MemberView<T>& mv)
00549     {
00550     out << (typename T::View) mv;
00551     return out;
00552     }
00553 
00554 /**
00555 * Assign the specified holder to NULL.
00556 *
00557 * @param mv the MemberView to clear
00558 */
00559 template<class T> void clear_handle(MemberView<T>& mv)
00560     {
00561     static TypedHandle<const T> vNull;
00562     mv = vNull;
00563     }
00564 
00565 /**
00566 * Return true if the supplied holder equals NULL.
00567 *
00568 * @param mv  the MemberView to test
00569 *
00570 * @return true iff the supplied MemberView equals NULL
00571 */
00572 template<class T>
00573 bool is_null(const MemberView<T>& mv)
00574     {
00575     return NULL == mv;
00576     }
00577 
00578 /**
00579 * Perform a dynamic cast the pointer associated with the MemberView
00580 * to a the specified handle/view type.
00581 *
00582 * @param mv      the MemberView from which to perform the cast
00583 * @param fThrow  true if an exception is to be thrown on a failed cast
00584 *
00585 * @return the casted pointer, or NULL if the cast fails and fThrow is false
00586 *
00587 * @throws ClassCastException if the cast fails and fThrow is true
00588 */
00589 template<class D, class T>
00590 D cast(const MemberView<T>& mv, bool fThrow = true)
00591     {
00592     return cast<D>((typename MemberView<T>::ValueView) mv, fThrow);
00593     }
00594 
00595 /**
00596 * Perform an instanceof check on a MemberView.
00597 *
00598 * @param mv  the MemberView from which to perform the test
00599 *
00600 * @return true if the supplied handle is an instance of the specified type
00601 */
00602 template<class D, class T>
00603 bool instanceof(const MemberView<T>& mv)
00604     {
00605     return NULL != cast<D>(mv, false);
00606     }
00607 
00608 /**
00609 * Compare a handle to a MemberView.
00610 *
00611 * @param h   handle to compare
00612 * @param mv  MemberView to compare
00613 *
00614 * @return true if both reference the same Object
00615 */
00616 template<class AT, class T>
00617 bool operator==(const TypedHandle<AT>& h, const MemberView<T>& mv)
00618     {
00619     return mv == h;
00620     }
00621 
00622 /**
00623 * Compare a Object pointer to a holder.
00624 *
00625 * @param cpo  handle to compare
00626 * @param mv   MemberView to compare
00627 *
00628 * @return true if both reference the same Object
00629 */
00630 template<class T>
00631 bool operator==(const Object* cpo, const MemberView<T>& mv)
00632     {
00633     return mv == cpo;
00634     }
00635 
00636 /**
00637 * Compare a handle to a holder.
00638 *
00639 * @param h   handle to compare
00640 * @param mv  MemberView to compare
00641 *
00642 * @return true if each references a different Object
00643 */
00644 template<class AT, class T>
00645 bool operator!=(const TypedHandle<AT>& h, const MemberView<T>& mv)
00646     {
00647     return mv != h;
00648     }
00649 
00650 /**
00651 * Compare a Object pointer to a MemberView.
00652 *
00653 * @param cpo  handle to compare
00654 * @param mv   holder to compare
00655 *
00656 * @return true if each references a different Object
00657 */
00658 template<class T>
00659 bool operator!=(const Object* cpo, const MemberView<T>& mv)
00660     {
00661     return mv != cpo;
00662     }
00663 
00664 COH_CLOSE_NAMESPACE2
00665 
00666 #endif // COH_MEMBER_VIEW_HPP
Copyright (c) 2000-2008 Oracle. All rights reserved.