// smarray.h (UNFINISHED)
// Glenn G. Chappell
// VERSION 3
// 30 Oct 2009
//
// For CS 311 Fall 2009
// Header for class SmArray
// Smart array class

#ifndef FILE_SMARRAY_H_INCLUDED
#define FILE_SMARRAY_H_INCLUDED

#include <cstdlib>    // for std::size_t
#include <algorithm>  // for std::copy


// ************************************************************************
// class SmArray - Class definition
// ************************************************************************


// class SmArray
// Smart array of ints
// Invariants:
//     capacity_ >= size_ >= 0.
//     capcity_ >= MINCAP.
//     data_ points to an int array, allocated with new [],
//      owned by *this, holding at least capacity_ ints.
class SmArray {

// ***** SmArray: types & constants *****
public:

    typedef std::size_t size_type;  // For array size & indices
    typedef int value_type;         // Type of data item in array
    typedef value_type * iterator;  // iterator types, as in the STL
    typedef const value_type * const_iterator;

private:

    enum { MINCAP = 10 };           // Minimum value of capacity_

// ***** SmArray: ctors, op=, dctor  *****
public:

    // Default ctor & ctor from size
    // Pre:
    // Post:
    // Strong Guarantee
    explicit SmArray(size_type theSize = 0)
        :capacity_(theSize < MINCAP ? MINCAP : theSize),
         size_(theSize),
         data_(new value_type[capacity_])
        // capacity_ must be declared before data_
    {}

    // Copy ctor
    // Pre:
    // Post:
    // Strong Guarantee
    SmArray(const SmArray & other)
        :capacity_(other.capacity_),
         size_(other.size_),
         data_(new value_type[other.capacity_])
    { std::copy(other.begin(), other.end(), begin()); }

    // Copy assignment
    // Pre:
    // Post:
    // ??? Guarantee
    SmArray & operator=(const SmArray & rhs);

    // Dctor
    // Pre:
    // Post:
    // No-Throw Guarantee
    ~SmArray()
    { delete [] data_; }

// ***** SmArray: General public functions *****
public:

    // operator[] (non-const & const)
    // Pre:
    // Post:
    // No-Throw Guarantee
    value_type & operator[](size_type index)
    { return data_[index]; }
    const value_type & operator[](size_type index) const
    { return data_[index]; }

    // size
    // Pre:
    // Post:
    // No-Throw Guarantee
    size_type size() const
    { return size_; }

    // empty
    // Pre:
    // Post:
    // No-Throw Guarantee
    bool empty() const
    { return size() == 0; }

    // begin (non-const & const)
    // Pre:
    // Post:
    // No-Throw Guarantee
    iterator begin()
    { return data_; }
    const_iterator begin() const
    { return data_; }

    // end (non-const & const)
    // Pre:
    // Post:
    // No-Throw Guarantee
    iterator end()
    { return data_ + size(); }
    const_iterator end() const
    { return data_ + size(); }

    // resize
    // Pre:
    // Post:
    // ??? Guarantee
    void resize(size_type newSize);

    // insert
    // Pre:
    // Post:
    // ??? Guarantee
    iterator insert(iterator pos,
                    const value_type & item);

    // remove
    // Pre:
    // Post:
    // ??? Guarantee
    iterator remove(iterator pos);

    // swap
    // Pre:
    // Post:
    // ??? Guarantee
    void swap(SmArray & other);

// ***** SmArray: Data members *****
private:

    size_type capacity_;  // Size of allocated space
    size_type size_;      // Number of data items stored
    value_type * data_;   // Pointer to our array
    // capacity_ must be declared before data_

};  // end class SmArray


#endif //#ifndef FILE_SMARRAY_H_INCLUDED

