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