coherence/lang/Array.hpp

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
Copyright (c) 2000-2008 Oracle. All rights reserved.