/*
**********************************************************************
*   Copyright (C) 1999-2003, International Business Machines
*   Corporation and others.  All Rights Reserved.
**********************************************************************
*/

//
//  UVector32 is a class implementing a vector of 32 bit integers.
//            It is similar to UVector, but holds int32_t values rather than pointers.
//            Most of the code is unchanged from UVector.
//

#ifndef UVECTOR32_H
#define UVECTOR32_H

#include "unicode/utypes.h"
#include "unicode/uobject.h"
#include "uhash.h"
#include "uassert.h"

U_NAMESPACE_BEGIN



/**
 * <p>Ultralightweight C++ implementation of a <tt>void*</tt> vector
 * that is (mostly) compatible with java.util.Vector.
 *
 * <p>This is a very simple implementation, written to satisfy an
 * immediate porting need.  As such, it is not completely fleshed out,
 * and it aims for simplicity and conformity.  Nonetheless, it serves
 * its purpose (porting code from java that uses java.util.Vector)
 * well, and it could be easily made into a more robust vector class.
 *
 * <p><b>Design notes</b>
 *
 * <p>There is index bounds checking, but little is done about it.  If
 * indices are out of bounds, either nothing happens, or zero is
 * returned.  We <em>do</em> avoid indexing off into the weeds.
 *
 * <p>There is detection of out of memory, but the handling is very
 * coarse-grained -- similar to UnicodeString's protocol, but even
 * coarser.  The class contains <em>one static flag</em> that is set
 * when any call to <tt>new</tt> returns zero.  This allows the caller
 * to use several vectors and make just one check at the end to see if
 * a memory failure occurred.  This is more efficient than making a
 * check after each call on each vector when doing many operations on
 * multiple vectors.  The single static flag works best when memory
 * failures are infrequent, and when recovery options are limited or
 * nonexistent.
 *
 * <p><b>To do</b>
 *
 * <p>Improve the handling of index out of bounds errors.
 *
 * @author Alan Liu
 */
class U_COMMON_API UVector32 : public UObject {
private:
    int32_t   count;

    int32_t   capacity;

    int32_t*  elements;

public:
    UVector32(UErrorCode &status);

    UVector32(int32_t initialCapacity, UErrorCode &status);

    ~UVector32();

    /**
     * Assign this object to another (make this a copy of 'other').
     * Use the 'assign' function to assign each element.
     */
    void assign(const UVector32& other, UErrorCode &ec);

    /**
     * Compare this vector with another.  They will be considered
     * equal if they are of the same size and all elements are equal,
     * as compared using this object's comparer.
     */
    UBool operator==(const UVector32& other);

    /**
     * Equivalent to !operator==()
     */
    inline UBool operator!=(const UVector32& other);

    //------------------------------------------------------------
    // java.util.Vector API
    //------------------------------------------------------------

    void addElement(int32_t elem, UErrorCode &status);

    void setElementAt(int32_t elem, int32_t index);

    void insertElementAt(int32_t elem, int32_t index, UErrorCode &status);
    
    int32_t elementAti(int32_t index) const;

    UBool equals(const UVector32 &other) const;

    int32_t lastElementi(void) const;

    int32_t indexOf(int32_t obj, int32_t startIndex = 0) const;

    UBool contains(int32_t obj) const;

    UBool containsAll(const UVector32& other) const;

    UBool removeAll(const UVector32& other);

    UBool retainAll(const UVector32& other);

    void removeElementAt(int32_t index);

    void removeAllElements();

    int32_t size(void) const;

    UBool isEmpty(void) const;

    // Inline.  Use this one for speedy size check.
    inline UBool ensureCapacity(int32_t minimumCapacity, UErrorCode &status);

    // Out-of-line, handles actual growth.  Called by ensureCapacity() when necessary.
    UBool expandCapacity(int32_t minimumCapacity, UErrorCode &status);

    /**
     * Change the size of this vector as follows: If newSize is
     * smaller, then truncate the array, possibly deleting held
     * elements for i >= newSize.  If newSize is larger, grow the
     * array, filling in new slows with zero.
     */
    void setSize(int32_t newSize);

    //------------------------------------------------------------
    // New API
    //------------------------------------------------------------

    /**
     * Returns true if this vector contains none of the elements
     * of the given vector.
     * @param other vector to be checked for containment
     * @return true if the test condition is met
     */
    UBool containsNone(const UVector32& other) const;


    /**
     * Insert the given integer into this vector at its sorted position.
     * The current elements are assumed to be sorted already.
     */
    void sortedInsert(int32_t obj, UErrorCode& ec);

    /**
     * Returns a pointer to the internal array holding the vector.
     */
    int32_t *getBuffer() const;

    /**
     * ICU "poor man's RTTI", returns a UClassID for this class.
     *
     * @draft ICU 2.2
     */
    static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }

    /**
     * ICU "poor man's RTTI", returns a UClassID for the actual class.
     *
     * @draft ICU 2.2
     */
    virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }

private:
    void _init(int32_t initialCapacity, UErrorCode &status);

    // Disallow
    UVector32(const UVector32&);

    // Disallow
    UVector32& operator=(const UVector32&);

    /**
     * The address of this static class variable serves as this class's ID
     * for ICU "poor man's RTTI".
     */
    static const char fgClassID;


    //  API Functions for Stack operations.
    //  In the original UVector, these were in a separate derived class, UStack.
    //  Here in UVector32, they are all together.
public:
    UBool empty(void) const;

    int32_t peeki(void) const;
    
    int32_t popi(void);
    
    int32_t push(int32_t i, UErrorCode &status);

    int32_t *reserveBlock(int32_t size, UErrorCode &status);
    int32_t *popFrame(int32_t size);
};


// UVector32 inlines

inline UBool UVector32::ensureCapacity(int32_t minimumCapacity, UErrorCode &status) {
    if (capacity >= minimumCapacity) {
        return TRUE;
    } else {
        return expandCapacity(minimumCapacity, status);
    }
}

inline int32_t UVector32::elementAti(int32_t index) const {
    return (0 <= index && index < count) ? elements[index] : 0;
}


inline void UVector32::addElement(int32_t elem, UErrorCode &status) {
    if (ensureCapacity(count + 1, status)) {
        elements[count] = elem;
        count++;
    }
}

inline int32_t *UVector32::reserveBlock(int32_t size, UErrorCode &status) {
    ensureCapacity(count+size, status);
    int32_t  *rp = elements+count;
    count += size;
    return rp;
}

inline int32_t *UVector32::popFrame(int32_t size) {
    U_ASSERT(count >= size);
    count -= size;
    if (count < 0) {
        count = 0;
    }
    return elements+count-size;
}



inline int32_t UVector32::size(void) const {
    return count;
}

inline UBool UVector32::isEmpty(void) const {
    return count == 0;
}

inline UBool UVector32::contains(int32_t obj) const {
    return indexOf(obj) >= 0;
}

inline int32_t UVector32::lastElementi(void) const {
    return elementAti(count-1);
}

inline UBool UVector32::operator!=(const UVector32& other) {
    return !operator==(other);
}

inline int32_t *UVector32::getBuffer() const {
    return elements;
};


// UStack inlines

inline UBool UVector32::empty(void) const {
    return isEmpty();
}

inline int32_t UVector32::peeki(void) const {
    return lastElementi();
}

inline int32_t UVector32::push(int32_t i, UErrorCode &status) {
    addElement(i, status);
    return i;
}

inline int32_t UVector32::popi(void) {
    int32_t result = 0;
    if (count > 0) {
        count--;
        result = elements[count];
    }
    return result;
}

U_NAMESPACE_END

#endif
