00001 /* 00002 * Array.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_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 provides 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 * 00179 * @throws IndexOutOfBoundsException if i is not a valid index 00180 */ 00181 inline ElementType& operator[](size32_t i) 00182 { 00183 if (i >= length) 00184 { 00185 coh_throw_ioob(i); 00186 } 00187 return raw[i]; 00188 } 00189 00190 /** 00191 * Return the element stored at the specified index. 00192 * 00193 * @param i the index into the Array 00194 * 00195 * @return the element stored at the specified index 00196 * 00197 * @throws IndexOutOfBoundsException if i is not a valid index 00198 */ 00199 inline const ElementType& operator[](size32_t i) const 00200 { 00201 if (i >= length) 00202 { 00203 coh_throw_ioob(i); 00204 } 00205 return raw[i]; 00206 } 00207 00208 /** 00209 * A region of this Array is compared to a region of a supplied Array. 00210 * 00211 * The Array regions are considered equal if each element of the 00212 * Array region is equal to the corresponding element in the other 00213 * Array region. 00214 * 00215 * In the case of Arrays of Objects this is a deep equality test, 00216 * that is each element in the supplied Array must reference an Object 00217 * which compares equal to the Object referenced from the same element 00218 * within this Array. 00219 * 00220 * @param ofSource the starting index in this Array where the 00221 * comparison begins 00222 * @param vaOther view to the Array to compare for equality 00223 * @param ofOther the starting index in the other Array where the 00224 * comparison begins 00225 * @param c the count of elements to compare, or npos for 00226 * (vaOther->length - ofOther) 00227 * 00228 * @return true iff the two Array regions are identical 00229 * 00230 * @throws IndexOutOfBoundsException if ofSource + c or ofOther + c 00231 * are out of their respective Array's bounds 00232 * 00233 * @since Coherence 3.7.1 00234 */ 00235 virtual bool regionMatches(size32_t ofSource, 00236 typename Array<T>::View vaOther, size32_t ofOther = 0, 00237 size32_t c = npos) const; 00238 00239 /** 00240 * Return an Array over a subset of the elements in this Array. The 00241 * returned Array is backed by this Array, and changes in one will 00242 * be reflected in the other. 00243 * 00244 * @param iFrom the starting index (inclusive) 00245 * @param iTo the ending index (exclusive), or npos 00246 * 00247 * @return the sub Array 00248 * 00249 * @throws IndexOutOfBoundsException if either index is out of the 00250 * Array's bounds 00251 */ 00252 virtual Handle subArray(size32_t iFrom, size32_t iTo); 00253 00254 /** 00255 * Return an Array over a subset of the elements in this Array. The 00256 * returned Array is backed by this Array, and changes in one will 00257 * be reflected in the other. 00258 * 00259 * @param iFrom the starting index (inclusive) 00260 * @param iTo the ending index (exclusive), or npos 00261 * 00262 * @return the sub Array 00263 * 00264 * @throws IndexOutOfBoundsException if either index is out of the 00265 * Array's bounds 00266 */ 00267 virtual View subArray(size32_t iFrom, size32_t iTo) const; 00268 00269 00270 // ----- Object interface ----------------------------------------------- 00271 00272 public: 00273 /** 00274 * {@inheritDoc} 00275 */ 00276 virtual void toStream(std::ostream& out) const; 00277 00278 /** 00279 * Return a hash of all the values in the Array. 00280 * 00281 * @return a hash of all the values in the Array 00282 */ 00283 virtual size32_t hashCode() const; 00284 00285 /** 00286 * Test two Arrays for equality. 00287 * 00288 * The Arrays are considered equal if they are of the same type and 00289 * length, and each element of the Array is equal to corresponding 00290 * element in the other Array. 00291 * 00292 * In the case of Arrays of Objects this is a deep equality test, 00293 * that is each element in the supplied Array must reference an Object 00294 * which compares equal to the Object referenced from the same element 00295 * within this Array. 00296 * 00297 * @param v view to the Array to compare for equality 00298 * 00299 * @return true iff the Arrays are identical 00300 */ 00301 virtual bool equals(Object::View v) const; 00302 00303 /** 00304 * Return true iff the Array and all of its elements are immutable. 00305 * 00306 * @return true iff the Array and all of its elements are immutable 00307 */ 00308 virtual bool isImmutable() const; 00309 00310 /** 00311 * Return the size in bytes of the Array. 00312 * 00313 * @return the size in bytes of the Array 00314 */ 00315 virtual size32_t sizeOf() const; 00316 00317 /** 00318 * {@inheritDoc} 00319 */ 00320 virtual Object::Handle clone() const; 00321 00322 protected: 00323 /** 00324 * {@inheritDoc} 00325 */ 00326 virtual void onConst(); 00327 00328 /** 00329 * {@inheritDoc} 00330 */ 00331 virtual void onEscape(bool fEscaped) const; 00332 00333 00334 // ----- static methods ------------------------------------------------- 00335 00336 public: 00337 /** 00338 * Perform a shallow copy of the elements from one Array to another. 00339 * 00340 * If the source and destination Arrays are the same, it is 00341 * allowable to have the source and destination ranges overlap, though 00342 * an intermediate copy may be performed internally. 00343 * 00344 * @param vaSrc the source Array 00345 * @param iSrc the source offset 00346 * @param haDes the destination Array 00347 * @param iDes the destination offset 00348 * @param ce the number of elements to copy; if npos then copy all 00349 * that is available without stepping out of bounds 00350 * 00351 * @return haDes 00352 * 00353 * @throws IndexOutOfBoundsException if either index is out of the 00354 * Array's bounds, or if haDes is too small 00355 */ 00356 static typename Array<T>::Handle copy(typename Array<T>::View vaSrc, 00357 size32_t iSrc, typename Array<T>::Handle haDes, 00358 size32_t iDes = 0, size32_t ce = npos); 00359 00360 /** 00361 * Compute the hashCode for the supplied raw array. 00362 * 00363 * @param aValue the array to hash 00364 * @param c the number of elements to hash 00365 */ 00366 static size32_t hashCode(const T* aValue, size32_t c); 00367 00368 00369 // ----- data members --------------------------------------------------- 00370 00371 00372 protected: 00373 /** 00374 * The cached hash of all the Array elements. The hash code is not 00375 * cached until the Array becomes immutable. A value of zero indicates 00376 * that a hash has not been cached. 00377 */ 00378 mutable size32_t m_nHashCode; 00379 00380 /** 00381 * The super Array in the case that this Array was produced by a call 00382 * to subArray. If non-NULL then this Array does not own the memory 00383 * associated with raw. This data member is here solely for the purpose 00384 * of ensuring that the Array which "owns" the raw array is kept alive 00385 * and potentially mutable. 00386 */ 00387 MemberHolder<Array<T> > m_ohDelegate; 00388 00389 public: 00390 /** 00391 * The number of elements in the Array. 00392 */ 00393 const size32_t length; 00394 00395 /** 00396 * The underlying Array of values. 00397 * 00398 * This inner class allows the raw array to inherit the Array Object's 00399 * constness. Direct usage of this data member is discouraged as it 00400 * does not provide any bounds checking safety. 00401 */ 00402 class MemberArray 00403 { 00404 // ----- constructors --------------------------------------- 00405 00406 public: 00407 /** 00408 * Construct MemberArray for the given array of values. 00409 */ 00410 MemberArray(T* aValue) 00411 : m_aValue(aValue) {} 00412 00413 // ---- operators ------------------------------------------- 00414 00415 public: 00416 /** 00417 * Provides a conversion of this MemberArray to the type 'T*' 00418 */ 00419 inline operator T*() 00420 { 00421 return m_aValue; 00422 } 00423 00424 /** 00425 * Provides a conversion of this constant MemberArray to the 00426 * type 'const T*' 00427 */ 00428 inline operator const T*() const 00429 { 00430 return m_aValue; 00431 } 00432 00433 // ----- data members --------------------------------------- 00434 00435 protected: 00436 /** 00437 * The underlying array of values as 'T*' 00438 */ 00439 T* m_aValue; 00440 00441 // ----- friends -------------------------------------------- 00442 00443 friend class Array<T>; 00444 } raw; 00445 }; 00446 00447 COH_CLOSE_NAMESPACE2 00448 00449 #endif // COH_ARRAY_HPP