00001 /* 00002 * BoxHandle.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_BOX_HANDLE_HPP 00017 #define COH_BOX_HANDLE_HPP 00018 00019 #include "coherence/lang/compatibility.hpp" 00020 00021 #include "coherence/lang/TypedHandle.hpp" 00022 00023 COH_OPEN_NAMESPACE2(coherence,lang) 00024 00025 00026 /** 00027 * A TypedHandle implementation which supports auto-boxing. 00028 * 00029 * To support boxing a managed class defines an inner-type named "BoxedType", 00030 * and includes a public static "create" method which takes that type. The 00031 * BoxedType defines the type which the BoxHandle can use to create a managed 00032 * object from. Alternatively the BoxHandle declaration can identify the 00033 * "BoxedType" via a secondary template parameter. 00034 * 00035 * Managed classes which wish to be auto-boxing may use this handle type 00036 * when defining their Handle and View definitions. See String as an 00037 * example. 00038 * 00039 * When used with integral types a natural ambiguity is introduced when 00040 * setting or comparing a BoxHandle to NULL, as it also an integral type. In 00041 * such cases one may the is_null(h) and clear_handle(h) helper functions to 00042 * ensure the correct behavior. 00043 * 00044 * BoxHandle can be configured as strict, or non-strict. In strict mode 00045 * (the default), derefencing a NULL BoxHandle will result in a 00046 * NullPointerException. In non-strict mode, dereferencing a BoxHandle will 00047 * result in the BoxedType's default value being returned. 00048 * 00049 * @author mf 2007.07.05 00050 */ 00051 template<class T, class B = typename T::BoxedType, bool fStrict = true> 00052 class BoxHandle 00053 : public TypedHandle<T> 00054 { 00055 // ----- typedefs ------------------------------------------------------- 00056 00057 typedef B BoxedType; 00058 00059 00060 // ----- constructors --------------------------------------------------- 00061 00062 public: 00063 /** 00064 * Create an empty BoxHandle. 00065 */ 00066 BoxHandle() 00067 : TypedHandle<T>() 00068 { 00069 } 00070 00071 /** 00072 * Create a new BoxHandle from the supplied BoxedType 00073 */ 00074 BoxHandle(const B& b) 00075 : TypedHandle<T>() 00076 { 00077 TypedHandle<T>::set(get_pointer(T::create(b))); 00078 } 00079 00080 /** 00081 * Create a new BoxHandle from the TypedHandle with a type conversion. 00082 */ 00083 template<class O> BoxHandle(const TypedHandle<O>& h) 00084 : TypedHandle<T>() 00085 { 00086 TypedHandle<T>::set(get_pointer(h)); 00087 } 00088 00089 /** 00090 * Create a new BoxHandle from the TypedHandle with a type conversion. 00091 */ 00092 template<class O> BoxHandle(TypedHandle<O>& h) 00093 : TypedHandle<T>() 00094 { 00095 TypedHandle<T>::set(get_pointer(h)); 00096 } 00097 00098 /** 00099 * Create a new BoxHandle from the raw pointer. 00100 */ 00101 BoxHandle(T* o) 00102 : TypedHandle<T>() 00103 { 00104 TypedHandle<T>::set(o); 00105 } 00106 00107 /** 00108 * The copy constructor. 00109 */ 00110 BoxHandle(const BoxHandle& h) 00111 : TypedHandle<T>(h) 00112 { 00113 TypedHandle<T>::set(h.get()); 00114 } 00115 00116 /** 00117 * The destructor. 00118 */ 00119 ~BoxHandle() 00120 { 00121 } 00122 00123 // ----- operators ------------------------------------------------------ 00124 00125 public: 00126 /** 00127 * The "boxing" operator. 00128 */ 00129 BoxHandle& operator=(const BoxedType& b) 00130 { 00131 TypedHandle<T>::set(get_pointer(T::create(b))); 00132 return *this; 00133 } 00134 00135 /** 00136 * The "unboxing" operator. 00137 * 00138 * @return a copy of the referenced Object 00139 */ 00140 operator BoxedType() const 00141 { 00142 const T* pT = TypedHandle<T>::get(); 00143 if (NULL == pT) 00144 { 00145 if (fStrict) 00146 { 00147 coh_throw_npe(typeid(T)); 00148 } 00149 return BoxedType(); 00150 } 00151 return (BoxedType) *pT; 00152 } 00153 00154 /** 00155 * The equality operator. 00156 */ 00157 template<class O> 00158 bool operator==(const TypedHandle<O>& v) const 00159 { 00160 return (const Object*) get_pointer(*this) == 00161 (const Object*) get_pointer(v); 00162 } 00163 00164 /** 00165 * The equality operator. 00166 */ 00167 bool operator==(const Object* cpo) const 00168 { 00169 return ((const Object*) get_pointer(*this)) == 00170 ((const Object*) cpo); 00171 } 00172 00173 /** 00174 * The equality operator. 00175 */ 00176 bool operator==(const BoxedType& b) const 00177 { 00178 const T* pT = TypedHandle<T>::get(); 00179 return NULL == pT ? BoxedType() == b : ((BoxedType) *pT) == b; 00180 } 00181 00182 /** 00183 * The inequality operator. 00184 */ 00185 template<class O> 00186 bool operator!=(const TypedHandle<O>& h) const 00187 { 00188 return !operator==(h); 00189 } 00190 00191 /** 00192 * The inequality operator. 00193 */ 00194 bool operator!=(const Object* cpo) const 00195 { 00196 return !operator==(cpo); 00197 } 00198 00199 /** 00200 * The inequality operator. 00201 */ 00202 bool operator!=(const BoxedType& b) const 00203 { 00204 return !operator==(b); 00205 } 00206 }; 00207 00208 COH_CLOSE_NAMESPACE2 00209 00210 #endif // COH_BOX_HANDLE_HPP