00001 /* 00002 * FinalHandle.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_FINAL_HANDLE_HPP 00017 #define COH_FINAL_HANDLE_HPP 00018 00019 #include "coherence/lang/compatibility.hpp" 00020 00021 #include "coherence/lang/MemberHandle.hpp" 00022 #include "coherence/lang/TypedHandle.hpp" 00023 00024 COH_OPEN_NAMESPACE2(coherence,lang) 00025 00026 /** 00027 * FinalHandle is an immutable thread-safe handle used by an Object to 00028 * reference its non-const child Objects. 00029 * 00030 * FinalHandles may either be initialized with a value at 00031 * construction-time, or thereafter via the initialize() function. A 00032 * FinalHandle may be initialized only if the following conditions 00033 * hold: 00034 * <ul> 00035 * <li> The FinalHandle has not already been initialized 00036 * (either during construction, or via <tt>initialize()</tt>) 00037 * <li> The FinalHandle has not escaped 00038 * </ul> 00039 * For example: 00040 * 00041 * @code 00042 * class Foo 00043 * : public class_spec<Foo> 00044 * { 00045 * friend class factory<Foo>; 00046 * 00047 * protected: 00048 * Foo() 00049 * : m_fhBar(self()) // construction without initialization 00050 * {} 00051 * 00052 * public: 00053 * void setBar(Bar::Handle hBar) 00054 * { 00055 * initialize(m_fhBar, hBar); // post-construction initialization 00056 * } 00057 * 00058 * private: 00059 * FinalHandle<Bar> m_fhBar; 00060 * }; 00061 * @endcode 00062 * 00063 * FinalHandles transfer the constness of their parent Object. When a 00064 * FinalHandle is accessed from within a const method of the enclosing 00065 * "parent" class, it will only provide const access to the Object which it 00066 * references. If the enclosing Object becomes only accessed via views the 00067 * FinalHandle will also automatically, and permanently switch its reference 00068 * type from a handle to a view. 00069 * 00070 * Note: In the rare case that a FinalHandle is declared via the mutable 00071 * keyword, the FinalHandle must be informed of this fact by setting 00072 * fMutable to true during construction. A mutable FinalHandle will 00073 * will return Handles from const methods of the class it is a data 00074 * member of. The FinalHandle cannot be reassigned to reference another 00075 * object. 00076 * 00077 * @author mf 2008.12.01 00078 * 00079 * @see FinalView 00080 * @see FinalHolder 00081 */ 00082 template<class T> 00083 class FinalHandle 00084 : public MemberHandle<T> 00085 { 00086 // ----- typedefs ------------------------------------------------------- 00087 00088 public: 00089 /** 00090 * The type of the values the holder can reference. 00091 */ 00092 typedef T ValueType; 00093 00094 /** 00095 * The Handle type for the referenced Object. 00096 */ 00097 typedef typename T::Handle ValueHandle; 00098 00099 /** 00100 * The View type for the referenced Object. 00101 */ 00102 typedef typename T::View ValueView; 00103 00104 00105 // -------- constructors ------------------------------------------------ 00106 00107 public: 00108 /** 00109 * Construct a new FinalHandle referencing NULL via a handle. 00110 * 00111 * @param oGuardian the object that protects this member 00112 */ 00113 FinalHandle(const Object& oGuardian) 00114 : MemberHandle<T>(oGuardian) 00115 { 00116 } 00117 00118 /** 00119 * Construct a new FinalHandle referencing specified Object. 00120 * 00121 * @param oGuardian the object that protects this member 00122 * @param that the object to reference 00123 */ 00124 FinalHandle(const Object& oGuardian, const ValueHandle& that) 00125 : MemberHandle<T>(oGuardian, that) 00126 { 00127 // Note: The underlying MemberHandle is initialized in the 00128 // INHERITED mutability state, allowing the FinalHandle to act 00129 // as a handle in non-const methods. 00130 } 00131 00132 /** 00133 * Construct a new FinalHandle referencing specified Object. 00134 * 00135 * @param oGuardian the object that protects this member 00136 * @param that the object to reference 00137 * @param fMutable true if the member is declared as mutable, false 00138 * if declared as const 00139 */ 00140 FinalHandle(const Object& oGuardian, const ValueHandle& that, bool fMutable) 00141 : MemberHandle<T>(oGuardian, that, fMutable) 00142 { 00143 } 00144 00145 00146 // ----- operators ------------------------------------------------------ 00147 00148 public: 00149 /** 00150 * Return a View to the referenced Object. 00151 * 00152 * @return a View to the referenced Object 00153 */ 00154 operator ValueView() const 00155 { 00156 return ValueView(MemberHandle<T>::m_po); 00157 } 00158 00159 /** 00160 * Return a Handle to the referenced Object. 00161 * 00162 * @return a Handle to the referenced Object 00163 */ 00164 operator ValueHandle() 00165 { 00166 return ValueHandle(MemberHandle<T>::m_po); 00167 } 00168 00169 /** 00170 * Return a View to the referenced Object. 00171 * 00172 * @return a View to the referenced Object 00173 */ 00174 template<class PT> 00175 operator TypedHandle<const PT>() const 00176 { 00177 return MemberHandle<T>::m_po; 00178 } 00179 00180 /** 00181 * Return a Handle to the referenced Object. 00182 * 00183 * @return a Handle to the referenced Object 00184 */ 00185 template<class PT> 00186 operator TypedHandle<PT>() 00187 { 00188 return MemberHandle<T>::m_po; 00189 } 00190 00191 /** 00192 * Return a TypedHolder to the referenced Object. 00193 * 00194 * @return a TypedHolder to the referenced Object 00195 * 00196 */ 00197 template<class PT> 00198 operator TypedHolder<PT>() const 00199 { 00200 return ValueView(MemberHandle<T>::m_po); 00201 } 00202 00203 /** 00204 * Return a TypedHolder to the referenced Object. 00205 * 00206 * @return a TypedHolder to the referenced Object 00207 */ 00208 template<class PT> 00209 operator TypedHolder<PT>() 00210 { 00211 return MemberHandle<T>::m_po; 00212 } 00213 00214 /** 00215 * Dereference the FinalHandle. 00216 * 00217 * @return a const pointer to the referenced Object 00218 */ 00219 const T* operator->() const 00220 { 00221 const T* cpo = MemberHandle<T>::m_po; 00222 if (NULL == cpo) 00223 { 00224 coh_throw_npe(typeid(const T)); 00225 } 00226 return cpo; 00227 } 00228 00229 /** 00230 * Dereference the FinalHandle. 00231 * 00232 * @return a const pointer to the referenced Object 00233 */ 00234 T* operator->() 00235 { 00236 if (MemberHandle<T>::m_nMutability >= MemberHandle<T>::CONST) 00237 { 00238 coh_throw_illegal_state( 00239 "attempt to access handle from const FinalHandle"); 00240 } 00241 00242 T* po = MemberHandle<T>::m_po; 00243 if (NULL == po) 00244 { 00245 coh_throw_npe(typeid(T)); 00246 } 00247 return po; 00248 } 00249 00250 private: 00251 /** 00252 * Blocked assignment operator. 00253 */ 00254 FinalHandle& operator=(const ValueHandle& that); 00255 00256 /** 00257 * Blocked assignment operator. 00258 */ 00259 FinalHandle& operator=(const FinalHandle<T>& that); 00260 00261 /** 00262 * Blocked assignment operator. 00263 */ 00264 FinalHandle& operator=(FinalHandle<T>& that); 00265 00266 00267 // ----- helper methods ------------------------------------------------- 00268 00269 protected: 00270 /** 00271 * Initialize the value of a FinalHandle after it is 00272 * constructed. A FinalHandle may be initialized only if the 00273 * following conditions hold: 00274 * <ul> 00275 * <li> The FinalHandle has not already been initialized 00276 * (either during construction, or via <tt>initialize()</tt>) 00277 * <li> The FinalHandle has not escaped 00278 * </ul> 00279 * 00280 * @param that the value to initialize this FinalHandle to 00281 */ 00282 void initialize(ValueHandle that) 00283 { 00284 if (MemberHandle<T>::m_po != NULL) 00285 { 00286 coh_throw_illegal_state( 00287 "attempt to multiply initialize FinalHandle"); 00288 } 00289 if (MemberHandle<T>::getGuardian()._isEscaped()) 00290 { 00291 coh_throw_illegal_state( 00292 "attempt to initialize FinalHandle after it has escaped"); 00293 } 00294 if (MemberHandle<T>::m_nMutability >= MemberHandle<T>::CONST) 00295 { 00296 coh_throw_illegal_state( 00297 "attempt to initialize const FinalHandle"); 00298 } 00299 00300 T* po = get_pointer(that); 00301 MemberHandle<T>::m_po = 00302 NULL == po || NULL == po->_attach(/*fEscaped*/ false) 00303 ? NULL : po; 00304 } 00305 00306 // ----- friends -------------------------------------------------------- 00307 00308 /** 00309 * @internal 00310 */ 00311 template<class _T, class H> friend void initialize(FinalHandle<_T>& fh, 00312 H that); 00313 }; 00314 00315 /** 00316 * Perform a dynamic cast the pointer associated with the FinalHandle 00317 * to a the specified handle/view type. 00318 * 00319 * @param h the FinalHandle from which to perform the cast 00320 * @param fThrow true if an exception is to be thrown on a failed cast 00321 * 00322 * @return the casted pointer, or NULL if the cast fails and fThrow is false 00323 * 00324 * @throws ClassCastException if the cast fails and fThrow is true 00325 */ 00326 template<class D, class T> 00327 D cast(FinalHandle<T>& h, bool fThrow = true) 00328 { 00329 return cast<D>((typename FinalHandle<T>::ValueHandle) h, fThrow); 00330 } 00331 00332 /** 00333 * Perform a dynamic cast the pointer associated with the FinalHandle 00334 * to a the specified handle/view type. 00335 * 00336 * @param h the FinalHandle from which to perform the cast 00337 * @param fThrow true if an exception is to be thrown on a failed cast 00338 * 00339 * @return the casted pointer, or NULL if the cast fails and fThrow is false 00340 * 00341 * @throws ClassCastException if the cast fails and fThrow is true 00342 */ 00343 template<class D, class T> 00344 D cast(const FinalHandle<T>& h, bool fThrow = true) 00345 { 00346 return cast<D>((typename FinalHandle<T>::ValueView) h, fThrow); 00347 } 00348 00349 /** 00350 * Perform an instanceof check on a FinalHandle. 00351 * 00352 * @param h the FinalHandle from which to perform the test 00353 * 00354 * @return true if the supplied handle is an instance of the specified type 00355 */ 00356 template<class D, class T> 00357 bool instanceof(FinalHandle<T>& h) 00358 { 00359 return NULL != cast<D>(h, false); 00360 } 00361 00362 /** 00363 * Perform an instanceof check on a FinalHandle. 00364 * 00365 * @param h the FinalHandle from which to perform the test 00366 * 00367 * @return true if the supplied handle is an instance of the specified type 00368 */ 00369 template<class D, class T> 00370 bool instanceof(const FinalHandle<T>& h) 00371 { 00372 return NULL != cast<D>(h, false); 00373 } 00374 00375 /** 00376 * Initialize the value of a FinalHandle after it is constructed. A 00377 * FinalHandle may be initialized only if the following conditions 00378 * hold: 00379 * <ul> 00380 * <li> The FinalHandle has not already been initialized to a 00381 * non-NULL value (either during construction, or via 00382 * <tt>initialize()</tt>) 00383 * <li> The FinalHandle has not escaped 00384 * </ul> 00385 * 00386 * @param h the FinalHandle to initialize 00387 * @param that the value to initialize this FinalHandle to 00388 */ 00389 template<class T, class H> 00390 void initialize(FinalHandle<T>& h, H that) 00391 { 00392 h.initialize(that); 00393 } 00394 00395 COH_CLOSE_NAMESPACE2 00396 00397 #endif // COH_FINAL_HANDLE_HPP