/*
author:
  seth from http://www.bierdatenbank.de
tab size:
  2 (otherwise hardly readable!)
*/
#ifndef __seth_standard_h
#define __seth_standard_h

#include <ctime>

namespace seth_std{
  template<typename T>
  int sgn(T, int=0);              // liefer sgn(a, sgn(0)) (vorzeichenfunktion)
  int pow(intint=2);            // liefer x^y x,y int, y>=0

  class mem_usage{                // speichernutzungs-informationen
  private:
    static int mem_in_use;        // momentan benutzter speicher
    static int max_mem_in_use;    // max. benutzter speicher
  public:
    mem_usage(){}
    static int get_max_mem();     // liefer max_mem_in_use
    static int mem_info(bool=1);  // speichernutzungs-informationen
    static int used_mem(int);     // speicher der benutzt wird
    static int released_mem(int); // speicher der freigegeben wird
  };

  class chronometer{              // zeitmessung
  private:
    clock_t t_start, t_end;
  public:
    chronometer(){}
    void start_time();            // starte uhr
    void stop_time();             // stoppe uhr
    unsigned time_info(bool=1);   // zeit_mess_informationen
  };

  template<typename T>
  class punkt2d{                  // punkt2d
  public:
    T x, y;                                         // koordinaten
    punkt2d(){}                                     // ctor
    punkt2d(T, T);                                  // ctor
    punkt2d(const punkt2d<T>& source);              // copy-ctor
    punkt2d<T>& operator=(const punkt2d<T>&);       // operator= (punkt2d)
    punkt2d<T>& operator=(T);                       // operator= (skalar)
    punkt2d<T>  operator-();                        // unitaerer operator -pt
    punkt2d<T>  operator+(const punkt2d<T>&) const// pt+pt = pt
    punkt2d<T>& operator+=(const punkt2d<T>&);      // pt+=pt = pt
    punkt2d<T>  operator+(T) const;                 // pt+s = pt (komponentenweise)
    punkt2d<T>& operator+=(T);                      // pt+=s = pt
    punkt2d<T>  operator-(const punkt2d<T>&) const// pt-pt = pt
    punkt2d<T>& operator-=(const punkt2d<T>&);      // pt-=pt = pt
    punkt2d<T>  operator-(T) const;                 // pt-s = pt (komponentenweise)
    punkt2d<T>& operator-=(T);                      // pt-=s = pt
    punkt2d<T>  operator*(const punkt2d<T>&) const// pt*pt = pt (komponentenweise)
    punkt2d<T>& operator*=(const punkt2d<T>&);      // pt*=pt = pt
//  friend punkt2d operator*(T, const punkt2d<T>&); // s*pt = pt (komponentenweise)
    punkt2d<T>  operator*(T) const;                 // pt*s = pt (komponentenweise)
    punkt2d<T>& operator*=(T);                      // pt*=s = pt
    punkt2d<T>  operator/(const punkt2d<T>&) const// pt/pt = pt (komponentenweise)
    punkt2d<T>& operator/=(const punkt2d<T>&);      // pt/=pt = pt
    punkt2d<T>  operator/(T) const;                 // pt/s = pt (komponentenweise)
    punkt2d<T>& operator/=(T);                      // pt/=s = pt
    bool operator==(const punkt2d<T>&) const;       // operator==
    bool operator!=(const punkt2d<T>&) const;       // operator!=
    bool operator< (const punkt2d<T>&) const;       // operator<
    bool operator<=(const punkt2d<T>&) const;       // operator<=
    bool operator> (const punkt2d<T>&) const;       // operator>
    bool operator>=(const punkt2d<T>&) const;       // operator>=
    bool operator==(T) const;                       // operator== (skalar)
    bool operator!=(T) const;                       // operator!= (skalar)
    bool operator< (T) const;                       // operator<  (skalar)
    bool operator<=(T) const;                       // operator<= (skalar)
    bool operator> (T) const;                       // operator>  (skalar)
    bool operator>=(T) const;                       // operator>= (skalar)
    punkt2d<T> abs() const;                         // absolutbetrag
    T norm() const;                                 // norm
    T norm2() const;                                // norm*norm
    T skp(punkt2d<T>) const;                        // standard-skalarprodukt
    void nrotate(int=1);                            // drehe einen moore-nachbarschafts-vektor
  };
  template<typename T>
  punkt2d<T> fabs(const punkt2d<T>&);               // absolutbetrag
}
#endif