/**
 * This file describes a low-level array template for objects that don't need construction.
 * Class described here is IRawArray.
 *
 *   IBM Open Class Library
 *   (C) Copyright International Business Machines Corporation,  1997
 *   Licensed Material - Program-Property of IBM - All Rights Reserved.
 *
 */

// Revision: 39 1.21.1.6 source/albert/graph2d/irawarr.hpp, 2d, ioc.v400, 980918 

#ifndef _IRAWARR_
#define _IRAWARR_

#include <ibase.hpp>
#include <idatstrm.hpp>

#if __IBMCPP__ >= 400
#pragma namemangling(compat)
#endif

#pragma pack(push,4)
#pragma enum(4)

/**
 * IRawArray provides a low level substitute for traditional C arrays created with malloc and free.
 * IRawArray provides a low level substitute for traditional C arrays created with malloc and free.
 * The storage is managed with the low-level heap storage routines.  ONLY PRIMITIVE TYPES
 * AND OBJECTS WITH NO VIRTUAL MEMBER FUNCTIONS MAY BE STORED IN IRAWARRAY!!.  Since IRawArray does
 * NOT call constructors for the space it allocates, objects with vtables will not be
 * properly initialized, most certainly resulting in mysterious crashes.
 * Note: IRawArray does not check whether allocation is successful. Before constructing
 * a new array, one should check if there is enough memory and use a reasonable size.
 */

template <class AType>
class IRawArray
{
  public:

	/**
	 * Creates an IRawArray of type AType of the specified size. The items of the array are not initialized.
	 */
    IRawArray( unsigned long size = 0 );

	/**
	 * Copy constructor.
	 */
    IRawArray( const IRawArray<AType>& source );

    ~IRawArray();

	/**
	 * Gets the item of type AType at the specified index.
	 */
    AType       value( unsigned long i ) const;

	/**
	 * Sets the item of the IRawArray at the specified index, to the specified value.
	 */
    void        setValue( unsigned long i,
                          const AType& p );
	/**
	 * Appends an item to an IRawArray, extending the size if needed.
	 */
    void        append( const AType& p );

	/**
	 * Returns a reference to the indexed object.There is no bound checking.
	 */
    AType&  operator[]( unsigned long i );

	/**
	 * Returns a constant reference to the indexed object. There is no bound checking.
	 */
    const AType&    operator[]( unsigned long i ) const;

	/**
	 * Returns the number of items in the IRawArray; in other words, the size of the array.
	 */
    unsigned long  numberOfValues() const;

	/**
	 * Returns the fixed "clumps" in which the size of an IRawArray is increased to prevent thrashing the storage allocator when append is called.
	 */
    unsigned long  growIncrement() const;

	/**
	 * Sets the fixed "clumps" in which the size of an IRawArray is increased to prevent thrashing the storage allocator when append is called.
	 */
    void        setGrowIncrement( unsigned long increment );

	/**
	 * Sets the size of the IRawArray to the specified size. Reallocates the heap block.
	 */
    void        resize( unsigned long newsize );

	/**
	 * Swaps the contents of the IRawArray with the specified array.
	 */
    void        swap( IRawArray<AType>& victim );

	/**
	 * Assignment operator.
	 */
    IRawArray<AType>& operator= (const IRawArray<AType>& obj );

	/**
	 * Tests two arrays for equality.
	 */
    bool        operator== (const IRawArray<AType>& obj ) const;

	/**
	 * Tests two arrays for inequality.
	 */
    bool        operator!= (const IRawArray<AType>& obj ) const;

	IDataStream&    operator>>= (IDataStream&) const;
	IDataStream&    operator<<= (IDataStream&);
	void writeToStream(IDataStream& toWhere) const;
	void readFromStream(IDataStream& toWhere);

  protected:
  private:

	unsigned long roundUpSize( unsigned long ) const;

    unsigned long   fGrowAmount;
    unsigned long   fArraySize;
    unsigned long   fNumberOfValues;
    AType*          fValues;
};

#pragma enum(pop)
#pragma pack(pop)

#if __IBMCPP__ >= 400
#pragma namemangling()
#endif

#include <irawarr.inl>

#endif // _IRAWARR_
