// This may look like C code, but it is really -*- C++ -*-
/*  Classe vecteurs de type non constant (template)     */
/*                    E. Aubourg, E. Lesquoy            */
/*        Modifs             R. Ansari 04/95            */

#ifndef RZVECT_SEEN
#define RZVECT_SEEN

#include "machdefs.h"
#include "pexceptions.h"
#include "perrors.h"

template <class T>
class RzVect EXC_AWARE {
public:
                    RzVect(int n, T* data);
                    RzVect(int n);
  virtual           ~RzVect();
  inline int&       NImgRef()         {return nImgRef;}
  inline int&       Shareable()       {return shareable;}   
  inline T&         operator[](int i);
  inline const T&   operator[](int i) const;
  int               IElem(int k) const;
  float             FElem(int k) const;
  double            DElem(int k) const;
  
  T*                p;
  int               nElt;
  
private:
  int           nImgRef;    // Combien d'images font reference au meme RzVect ?
                                                // Le constructeur le met a *** 1 ***
                                                // Donc une image doit le changer lorsqu'elle pointe sans allouer.
  int           shareable;  // Dit si le RzVect peut etre partage. Mis a 0 par exemple si
                            // le tableau de nombres est en memoire partagee.
  int           ownTable;   // Dit si le RzVect peut faire delete du tableau.
};

template <class T>
inline T& RzVect<T>::operator[](int i)
{
  #ifdef RGCHECK
  if (i<0 || i>=nElt) THROW(rangeCheckErr);
  #endif
  return p[i];
}

template <class T>
inline const T& RzVect<T>::operator[](int i) const
{
  #ifdef RGCHECK
  if (i<0 || i>=nElt) THROW(rangeCheckErr);
  #endif
  return p[i];
}

template <class T>
inline int RzVect<T>::IElem(int k) const
{
  return (int) (*this)[k];
}

template <class T>
inline float RzVect<T>::FElem(int k) const
{
  return (float) (*this)[k];
}

template <class T>
inline double RzVect<T>::DElem(int k) const
{
  return (double) (*this)[k];
}

#endif

