/*******************************************************************************
+
+  LEDA 3.5
+
+  integer_vector.h
+
+  This file is part of the LEDA research version (LEDA-R) that can be 
+  used free of charge in academic research and teaching. Any commercial
+  use of this software requires a license which is distributed by the
+  LEDA Software GmbH, Postfach 151101, 66041 Saarbruecken, FRG
+  (fax +49 681 31104).
+
+  Copyright (c) 1991-1997  by  Max-Planck-Institut fuer Informatik
+  Im Stadtwald, 66123 Saarbruecken, Germany     
+  All rights reserved.
+ 
*******************************************************************************/
//---------------------------------------------------------------------
// file generated by notangle from integer_vector.lw
// please debug or modify LEDA web file
// mails and bugs: leda@mpi-sb.mpg.de
// based on LEDA architecture by S. Naeher, C. Uhrig
// coding: K. Mehlhorn, M. Seel
//---------------------------------------------------------------------

/*{\Msubst
RTINT integer
quotient rational
}*/

#ifndef LEDA_INTEGER_VECTOR_DECL_H
#define LEDA_INTEGER_VECTOR_DECL_H

#if !defined(LEDA_ROOT_INCL_ID)
#define LEDA_ROOT_INCL_ID 350065
#include <LEDA/REDEFINE_NAMES.h>
#endif

#include <math.h>
#include <ctype.h>
#include <LEDA/basic.h>
#include <LEDA/memory.h>

#include <LEDA/integer.h>
#include <LEDA/rational.h>

typedef integer RTINT;
typedef rational quotient;

#if defined(sgi) && !defined(__GNUC__)
#define RTINT integer
#endif

class integer_matrix;

/*{\Manpage {integer_vector} {} {Vectors with Integer Entries}}*/

  
  class integer_vector
  {

  /*{\Mdefinition An instance of data type |integer_vector| is a vector of
  variables of type |integer|, the so called ring type.  Together with the
  type |integer_matrix| it realizes the basic operations of linear
  algebra. Internal correctness tests are executed if compiled with the
  flag \texttt{LA\_SELFTEST}.}*/

    friend class integer_matrix;

    RTINT* v;
    int d;

    
    inline void allocate_vec_space(RTINT*& vi, int di)
    {
    /* We use this procedure to allocate memory. We use the more efficient
       LEDA scheme. We first get an appropriate piece of memory from the
       memory manager and then initialize each cell by an inplace new. */

      vi = (RTINT*)std_memory.allocate_bytes(di*sizeof(RTINT));
      RTINT* p = vi + di - 1;
      while (p >= vi) { new(p) RTINT;  p--; }   
    }

    inline void deallocate_vec_space(RTINT* vi, int di)
    {
    /* We use this procedure to deallocate memory. We have to free it by
       the LEDA scheme. We first call the destructor for type RTINT for each
       cell of the array and then return the piece of memory to the memory
       manager. */

      RTINT* p = vi + di - 1;
      while (p >= vi)  { p->~RTINT(); p--; }
      std_memory.deallocate_bytes(vi, di*sizeof(RTINT));
      vi = (RTINT*)nil;
    }


    inline void 
    check_dimensions(const integer_vector& vec) const
    { 
      LEDA_PRECOND((d == vec.d), "integer_vector::check_dimensions:\
      object dimensions disagree.")
    }

    // LEDA_MEMORY(integer_vector)

  public:

  /*{\Mcreation v 5}*/

  integer_vector()
  { d = 0; v = (RTINT*)nil; }
  /*{\Mcreate creates an instance |\Mvar| of type |\Mname|. 
              |\Mvar| is initialized to the zero-dimensional vector.}*/

  integer_vector(int d); 
  /*{\Mcreate creates an instance |\Mvar| of type |\Mname|. 
              |\Mvar| is initialized to a vector of dimension $d$.}*/ 

  integer_vector(const RTINT& a, const RTINT& b);
  /*{\Mcreate creates an instance |\Mvar| of type |\Mname|.
              |\Mvar| is initialized to the two-dimensional vector $(a,b)$.}*/

  integer_vector(const RTINT& a, const RTINT& b, const RTINT& c);
  /*{\Mcreate creates an instance |\Mvar| of type |\Mname|. 
              |\Mvar| is initialized to the three-dimensional vector 
              $(a,b,c)$.}*/

  integer_vector(const RTINT& a, const RTINT& b, const RTINT& c, const RTINT& d);
  /*{\Mcreate creates an instance |\Mvar| of type |\Mname|; 
              |\Mvar| is initialized to the four-dimensional vector 
              $(a,b,c,d)$.}*/

  integer_vector(const integer_vector&);

  integer_vector& operator=(const integer_vector&);

  ~integer_vector() 
  { if (d > 0) deallocate_vec_space(v,d); }


  /*{\Moperations 3.3 4.5}*/

  int  dim() const { return d; }
  /*{\Mop       returns the dimension of |\Mvar|.}*/ 

    
  RTINT& operator[](int i)
  /*{\Marrop     returns $i$-th component of |\Mvar|.\\
                 \precond $0\le i \le \mbox{|v.dim()-1|}$. }*/
  { 
    LEDA_OPT_PRECOND((0<=i && i<d), "integer_vector::operator[]: \
    index out of range.")
    return v[i]; 
  }
    
  RTINT operator[](int i) const
  { 
    LEDA_OPT_PRECOND((0<=i && i<d), "integer_vector::operator[]: \
    index out of range.")
    return v[i]; 
  }

  integer_vector& operator+=(const integer_vector& v1);
  /*{\Mbinop     Addition plus assignment.\\
                 \precond |v.dim() == v1.dim()|.}*/

  integer_vector& operator-=(const integer_vector& v1);
  /*{\Mbinop     Subtraction plus assignment.\\
                 \precond |v.dim() == v1.dim()|.}*/
   
  integer_vector  operator+(const integer_vector& v1) const;
  /*{\Mbinop     Addition.\\
                 \precond |v.dim() == v1.dim()|.}*/

  integer_vector  operator-(const integer_vector& v1) const;
  /*{\Mbinop     Subtraction.\\
                 \precond |v.dim() = v1.dim()|.}*/

  RTINT  operator*(const integer_vector& v1) const;
  /*{\Mbinop     Inner Product.\\
                 \precond |v.dim() = v1.dim()|.}*/

  integer_vector  compmul(const RTINT& r) const;

  friend integer_vector 
  operator*(const RTINT& r, const integer_vector& v)
  { return v.compmul(r); } 
  /*{\Mbinopfunc     Componentwise multiplication with number $r$.}*/

  friend integer_vector 
  operator*(const integer_vector& v, const RTINT& r)
  { return v.compmul(r); }
  /*{\Mbinopfunc     Componentwise multiplication with number $r$.}*/

  integer_vector  operator-() const;


  bool     operator==(const integer_vector& w) const;
  bool     operator!=(const integer_vector& w) const 
  { return !(*this == w); }


  friend ostream& operator<<(ostream& O, const integer_vector& v);
  /*{\Mbinopfunc   writes |\Mvar| componentwise to the output stream $O$.}*/

  friend istream& operator>>(istream& I, integer_vector& v);
  /*{\Mbinopfunc   reads |\Mvar| componentwise from the input stream $I$.}*/


  static int  cmp(const integer_vector&, 
                  const integer_vector&);

  };



  ostream& operator<<(ostream&, const integer_vector&);
  istream& operator>>(istream&, integer_vector&);


  inline int  compare(const integer_vector& x, 
                      const integer_vector& y)
  { return integer_vector::cmp(x,y); }



  /*{\Mimplementation Vectors are implemented by arrays of type
  |integer|. All operations on a vector |v| take time $O(\mbox{|v.dim()|})$,
  except for |dimension| and $[\ ]$ which take constant time. The space
  requirement is $O(\mbox{|v.dim()|})$. }*/




#if LEDA_ROOT_INCL_ID == 350065
#undef LEDA_ROOT_INCL_ID
#include <LEDA/UNDEFINE_NAMES.h>
#endif

#endif // LEDA_INTEGER_VECTOR_DECL_H



