#ifndef ARRAY_OF_REF_H
#define ARRAY_OF_REF_H

#ifndef ARRAY_OF_H
#include "Array_of.h"
#endif

#ifndef ARRAY_H
#include "Array.h"
#endif

//#ifndef REF_H
//#include "Ref.h"
//#endif

#ifndef LIVING_H
#include "Living.h"
#endif

#ifdef WIN32
#pragma warning (disable : 4786)
#endif

namespace MM
{

template <class T>
class Array_of_ref : public Array_of <T>
{
//    Array <Ref <T> >    impl_;
    Array <T*>          impl_;

public:
    virtual int         size ()            const    {return impl_.size ();}
    virtual T &         operator[] (int i)          {return *impl_[i];}
    virtual const T &   operator[] (int i) const    {return *impl_[i];}

    virtual  T &        front()                     {return *impl_.front();}
    virtual const T &   front() const               {return *impl_.front();}
    virtual T &         back()                      {return *impl_.back();}
    virtual const T &   back() const                {return *impl_.back();}

    //virtual void        push_back (T & item) {impl_.push_back (Ref <T> (item));}
    //void                put (int index, T & item) {impl_[index]=Ref <T> (item);}
    //void                remove_at (int index)     {impl_.remove_at (index);}
    virtual void        push_back (T & item) {impl_.push_back (&item);}
    //void                put (int index, T & item) {impl_[index]=Ref <T> (item);}
    //void                remove_at (int index)     {impl_.remove_at (index);}

    void remove (T & item)
    {
        for (int i = 0;  i < size();  ++i)
        {
            if (impl_[i] == &item)
            {
                //impl_.remove_at (i);
                impl_.erase (impl_.begin() + i);
                return;
            }
        }
        FLAW ("No such reference.");
    }
    void                clear()                     {impl_.clear();}

    void remove_deads ()
    {
        int removed = MM::remove_deads (impl_.begin(), impl_.end());
        impl_.erase (impl_.end()-removed, impl_.end());
    }

    void stable_remove_deads ()
    {
        for (int i=0;  i<impl_.size();  ++i)
            if (impl_[i]->is_dead())
                impl_[i] = static_cast<T*>(0);

        impl_.erase (stable_remove
            (impl_.begin(), impl_.end(), static_cast<T*>(0)), impl_.end());
    }
};

}//MM

#endif //ARRAY_OF_REF_H

