coherence/lang/Array.hpp

00001 /*
00002 * Array.hpp
00003 *
00004 * Copyright (c) 2000, 2009, 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_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++ 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_iiob(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_iiob(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
Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.