Oracle Coherence for C++ API
Release 3.7.1.0
E22845-01
00001 /* 00002 * MemberView.hpp 00003 * 00004 * Copyright (c) 2000, 2011, 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 ? forever_mutable : safe_immutable), 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 >= forever_immutable) 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 >= forever_immutable) 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 >= forever_immutable) 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_immutable || !oGuardian._isEscaped()) 00328 { 00329 // non-escaped, or safe_immutable, 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