// Vecteur.h: interface for the Vecteur class.
//
//////////////////////////////////////////////////////////////////////

#ifndef __VECTEUR_HXX__
#define __VECTEUR_HXX__

#include <exception>
#include <stdexcept>

using namespace std;

class Vecteur  
{
  public:
    class Exception : public std::exception {};
    class DepassementCapacite : public Vecteur::Exception {}; 
    class Allocation : public Vecteur::Exception {};
    class EnDehorsDesBornes : public Vecteur::Exception {};
  public:

    ///////////////////////////////////////////
    // Elements de la forme standard de coplien
    ///////////////////////////////////////////

    // Constructeur par défaut

    Vecteur(int capacite=16):
      capacite_(capacite),
      taille_(0)
    {
      if (capacite_)
      {
        tab_=new int [capacite_];

        if (! tab_)
          throw Vecteur::Allocation();

      }
      else
        tab_=0;
    }

    // Constructeur de recopie

    Vecteur(const Vecteur &a)
    {
      clone(a);
    }

    // Destructeur

	  virtual ~Vecteur()
    {
      delete [] tab_;
    }

    // Opérateur d'affectation

    Vecteur &operator=(const Vecteur &a)
    {
      delete [] tab_;
      clone(a);
      return *this;
    }

    ///////////////////////////////////////////
    // Fin de la forme standard de coplien
    ///////////////////////////////////////////


    // Opérateur [] permettant un accès indexé
    // aux éléments du vecteur

    const int &operator[](int index) const
    {
      if ((index < 0) || (index >= capacite_))
        throw Vecteur::EnDehorsDesBornes();
      return tab_[index];
    }

    // Ajout d'un élément

    void pushBack(int valeur)
    {
      tab_[taille_]=valeur;
      taille_++;
    }

    // Accès aux attributs

    int taille(void) const
    {
      return taille_;
    }

    int capacite(void) const
    {
      return capacite_;
    }

  private:

    // Méthode de clonage utilisée en interne 
    // par le constructeur de recopie et l'opérateur
    // d'affectation

    void clone(const Vecteur &a)
    {
      capacite_=a.capacite_;
      taille_=a.taille_;
      if (capacite_)
      {
        tab_=new int [capacite_];

        if (! tab_)
          throw Vecteur::Allocation();
      
        if (taille_)
        {

          int *source=a.tab_;
          int *destination=tab_;

          for (int i=0;
               i<taille_;
               i++,source++,destination++)
            *destination=*source;
        }
      }
      else
        tab_=0;
    }

// Code a rajouter si l'on utilise friend
#ifdef __PAR_ICI_L_AMI__
    friend ostream &operator<<(ostream &, const Vecteur &);
#endif


  private:
    int  capacite_;
    int  taille_;
    int *tab_;
};

#ifndef __PAR_ICI_L_AMI__

ostream &operator << (ostream &, const Vecteur &);

#endif

#endif 
