00001 /* 00002 * Array.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_ARRAY_HPP 00017 #define COH_ARRAY_HPP 00018 00019 #include "coherence/lang/compatibility.hpp" 00020 00021 #include "coherence/lang/Object.hpp" 00022 #include "coherence/lang/MemberHolder.hpp" 00023 #include "coherence/lang/SmartMember.hpp" 00024 #include "coherence/lang/SubscriptHandle.hpp" 00025 00026 #include <ostream> 00027 00028 COH_OPEN_NAMESPACE2(coherence,lang) 00029 00030 extern COH_EXPORT void coh_throw_iiob(size32_t i); 00031 00032 00033 /** 00034 * A fixed size collection of values, indexed by integer position. 00035 * 00036 * Array is a wrapper around standard C++ array's, adding thread-safety and 00037 * memory management. Array does not provide bounds checks however it does 00038 * provide a "length" field which can be used to safely determine the last 00039 * index of the array. 00040 * 00041 * Array's handle type supports direct subscripting: 00042 * 00043 * @code 00044 * for (size32_t i = 0, c = hArr->length; i < c; ++i) 00045 * { 00046 * std::cout << hArr[i] << std::endl; 00047 * } 00048 * @endcode 00049 * 00050 * Only a limited number of element types are supported, including: 00051 * bool, octect_t, char, wchar_t, char16_t, int8_t, uint8_t, int16_t, 00052 * uint16_t, int32_t, uint32_t, int64_t, uint64_t, float32_t, and float64_t. 00053 * 00054 * Arrays of Handles and Views to Objects are supported via ObjectArray. 00055 * 00056 * @see ObjectArray 00057 * 00058 * @author mf 2007.07.05 00059 */ 00060 template<class T> 00061 class COH_EXPORT Array 00062 : public cloneable_spec<Array<T> > 00063 { 00064 friend class factory<Array<T> >; 00065 00066 // ----- constants ------------------------------------------------------ 00067 00068 public: 00069 /** 00070 * The largest possible value of type size32_t. 00071 */ 00072 static const size32_t npos = size32_t(-1); 00073 00074 00075 // ----- handle definitions --------------------------------------------- 00076 00077 public: 00078 /** 00079 * Handle definition. 00080 */ 00081 typedef SubscriptHandle<Array<T>, T> Handle; 00082 00083 /** 00084 * View definition. 00085 */ 00086 typedef SubscriptHandle<const Array<T>, const T> View; 00087 00088 00089 // ----- typedefs ------------------------------------------------------- 00090 00091 public: 00092 /** 00093 * Element type 00094 */ 00095 typedef T ElementType; 00096 00097 00098 // ----- factory methods ------------------------------------------------ 00099 00100 public: 00101 /** 00102 * Create a new Array instance. 00103 * 00104 * @param cValue the length of the returned Array 00105 */ 00106 static Handle create(size32_t cValue = 0); 00107 00108 00109 // ----- constructors --------------------------------------------------- 00110 00111 protected: 00112 /** 00113 * Create a new Array instance. 00114 * 00115 * @param cValue the length of the returned Array 00116 */ 00117 Array(size32_t cValue = 0); 00118 00119 /** 00120 * @internal 00121 * 00122 * Create a new array which is a sub-array of an existing array. 00123 * 00124 * The new array uses the same storage as the original, and an update 00125 * to one will be reflected in the other. If this method is supplied 00126 * with a View to an Array, the caller must store the resulting created 00127 * array as a View. Storing as a Handle is not const correct. It is 00128 * for this reason that this constuctor is not made available via a 00129 * create method, instead it should be safely accessed via the 00130 * subArray methods. 00131 * 00132 * @param oha the array to delegate to 00133 * @param iFrom the starting index (inclusive) 00134 * @param iTo the ending index (exclusive), or npos 00135 * 00136 * @see subArray 00137 */ 00138 Array(typename Array<T>::Holder oha, size32_t iFrom, size32_t iTo); 00139 00140 /** 00141 * Copy constructor. 00142 * 00143 * The elements in the array will be copied, thus in the case of an 00144 * Array of Objects, the elements will be cloned. 00145 */ 00146 Array(const Array& that); 00147 00148 /** 00149 * @internal 00150 */ 00151 virtual ~Array(); 00152 00153 00154 // ----- Array interface ------------------------------------------------ 00155 00156 public: 00157 /** 00158 * Return the element stored at the specified index. 00159 * 00160 * @return the element stored at the specified index 00161 * @throws IndexOutOfBoundsException if i is not a valid index 00162 */ 00163 inline ElementType& operator[](size32_t i) 00164 { 00165 if (i >= length) 00166 { 00167 coh_throw_iiob(i); 00168 } 00169 return raw[i]; 00170 } 00171 00172 /** 00173 * Return the element stored at the specified index. 00174 * 00175 * @return the element stored at the specified index 00176 * @throws IndexOutOfBoundsException if i is not a valid index 00177 */ 00178 inline const ElementType& operator[](size32_t i) const 00179 { 00180 if (i >= length) 00181 { 00182 coh_throw_iiob(i); 00183 } 00184 return raw[i]; 00185 } 00186 00187 /** 00188 * Return an Array over a subset of the elements in this Array. The 00189 * returned array is backed by this array, and changes in one will 00190 * be reflected in the other. 00191 * 00192 * @param iFrom the starting index (inclusive) 00193 * @param iTo the ending index (exclusive), or npos 00194 * 00195 * @return the sub Array 00196 * 00197 * @throws IndexOutOfBoundsException if either index is out of the 00198 * Array's bounds. 00199 */ 00200 virtual Handle subArray(size32_t iFrom, size32_t iTo); 00201 00202 /** 00203 * Return an Array over a subset of the elements in this Array. The 00204 * returned array is backed by this array, and changes in one will 00205 * be reflected in the other. 00206 * 00207 * @param iFrom the starting index (inclusive) 00208 * @param iTo the ending index (exclusive), or npos 00209 * 00210 * @return the sub Array 00211 * 00212 * @throws IndexOutOfBoundsException if either index is out of the 00213 * Array's bounds. 00214 */ 00215 virtual View subArray(size32_t iFrom, size32_t iTo) const; 00216 00217 00218 // ----- Object interface ----------------------------------------------- 00219 00220 public: 00221 /** 00222 * {@inheritDoc} 00223 */ 00224 virtual void toStream(std::ostream& out) const; 00225 00226 /** 00227 * Return a hash of all the values in the array. 00228 * 00229 * @return a hash of all the values in the array. 00230 */ 00231 virtual size32_t hashCode() const; 00232 00233 /** 00234 * Test two Arrays for equality. 00235 * 00236 * The arrays are considered equal if they are of the same type and 00237 * length, and each element of the array is equal to corresponding 00238 * element in the other array. 00239 * 00240 * In the case of arrays of Objects this is a deep equality test, 00241 * that is each element in the supplied array must reference an Object 00242 * which compares equal to the Object refrenced from the same element 00243 * within this array. 00244 * 00245 * @param v view to the Array to compare for equality 00246 * 00247 * @return true iff the arrays are identical 00248 */ 00249 virtual bool equals(Object::View v) const; 00250 00251 /** 00252 * Return true iff the Array and all of its elements are immutable. 00253 * 00254 * @return true iff the Array and all of its elements are immutable. 00255 */ 00256 virtual bool isImmutable() const; 00257 00258 /** 00259 * Return the size in bytes of the array. 00260 * 00261 * @return the size in bytes of the array. 00262 */ 00263 virtual size32_t sizeOf() const; 00264 00265 protected: 00266 /** 00267 * {@inheritDoc} 00268 */ 00269 virtual void onConst(); 00270 00271 00272 // ----- static mehtods ------------------------------------------------- 00273 00274 public: 00275 /** 00276 * Perform a shallow copy of the elements from one array to another. 00277 * 00278 * The if the source and destination arrays are the same, it is 00279 * allowable to have the source and destination ranges overlap, though 00280 * an intermediate copy may be performed internally. 00281 * 00282 * @param vaSrc the source array 00283 * @param iSrc the source offset 00284 * @param haDes the destination aray 00285 * @param iDes the destination offset 00286 * @param ce the number of elements to copy; if npos then copy all 00287 * that is available without stepping out of bounds 00288 * 00289 * @return haDes 00290 * 00291 * @throws IndexOutOfBoundsException if either index is out of the 00292 * Array's bounds, of if haDes is too small 00293 */ 00294 static typename Array<T>::Handle copy(typename Array<T>::View vaSrc, 00295 size32_t iSrc, typename Array<T>::Handle haDes, 00296 size32_t iDes = 0, size32_t ce = npos); 00297 00298 00299 // ----- data members --------------------------------------------------- 00300 00301 00302 protected: 00303 /** 00304 * The cached hash of all the array elements. The hash code is not 00305 * cached until the array becomes immutable. A value of zero indicates 00306 * that a hash has not been cached. 00307 */ 00308 mutable size32_t m_nHashCode; 00309 00310 /** 00311 * The super Array in the case that this Array was produced by a call 00312 * to subArray. If non-NULL then this Array does not own the memory 00313 * associated with raw. This data member is here soley for the purposes 00314 * of ensuring that the Array which "owns" the raw array is kept alive, 00315 * and potentially mutable. 00316 */ 00317 MemberHolder<Array<T> > m_ohDelegate; 00318 00319 public: 00320 /** 00321 * The number of elements in the Array. 00322 */ 00323 const size32_t length; 00324 00325 /** 00326 * The underlying array of values. 00327 * 00328 * This inner class allows the value[] to inherit the Array Object's 00329 * constness. Direct usage of this data member is discouraged as it 00330 * does not provide any bounds checking safety. 00331 */ 00332 class MemberArray 00333 { 00334 // ----- constructors --------------------------------------- 00335 00336 public: 00337 /** 00338 * Construct empty MemberArray. 00339 */ 00340 MemberArray() 00341 : m_aValue(NULL) 00342 { 00343 } 00344 00345 /** 00346 * Construct MemberArray for the given array of values. 00347 */ 00348 MemberArray(T* aValue) 00349 : m_aValue(aValue) 00350 { 00351 } 00352 00353 /** 00354 * Destruct this MemberArray 00355 */ 00356 ~MemberArray() 00357 { 00358 if (m_aValue != NULL) 00359 { 00360 delete[] m_aValue; 00361 } 00362 } 00363 00364 // ---- operators ------------------------------------------- 00365 00366 public: 00367 /** 00368 * Provides a conversion of this MemberArray to the type 'T*' 00369 */ 00370 inline operator T*() 00371 { 00372 return m_aValue; 00373 } 00374 00375 /** 00376 * Provides a conversion of this constant MemberArray to the 00377 * type 'const T*' 00378 */ 00379 inline operator const T*() const 00380 { 00381 return m_aValue; 00382 } 00383 00384 // ----- data members --------------------------------------- 00385 00386 protected: 00387 /** 00388 * The underlying array of values as 'T*' 00389 */ 00390 T* m_aValue; 00391 00392 // ----- friends -------------------------------------------- 00393 00394 friend class Array<T>; 00395 } raw; 00396 }; 00397 00398 COH_CLOSE_NAMESPACE2 00399 00400 #endif // COH_ARRAY_HPP