/*
**  CXSC is a C++ library for eXtended Scientific Computing
**
**  Copyright (C) 1990-2000 Institut fuer Angewandte Mathematik,
**                          Universitaet Karlsruhe, Germany
**            (C) 2000-2001 Wiss. Rechnen/Softwaretechnologie
**                          Universitaet Wuppertal, Germany   
**
**  This library is free software; you can redistribute it and/or
**  modify it under the terms of the GNU Library General Public
**  License as published by the Free Software Foundation; either
**  version 2 of the License, or (at your option) any later version.
**
**  This library is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
**  Library General Public License for more details.
**
**  You should have received a copy of the GNU Library General Public
**  License along with this library; if not, write to the Free
**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/* CVS $Id: idot.hpp,v 1.3 2001/08/09 11:37:55 cxsc Exp $ */

#ifndef CXSC_IDOT_HPP_INCLUDED
#define CXSC_IDOT_HPP_INCLUDED

#include <iostream>
#include <string>
#include "dot.hpp"
#include "interval.hpp"

namespace cxsc {

class idotprecision
{
   private:
      // ---- Datenelemente ---------------------------------------
      dotprecision inf,sup;

   public:
      // ---- Constructors  ---------------------------------------
      idotprecision() {}
      inline idotprecision(const dotprecision&, const dotprecision&) throw(ERROR_IDOTPRECISION_EMPTY_INTERVAL);
      inline idotprecision(const idotprecision&);
      
      // explicit inline idotprecision(int n) : inf(n), sup(n)      { }
      // explicit inline idotprecision(int a,int b) : inf(a), sup(b) { }
      // explicit inline idotprecision(const double &d) : inf(d), sup(d) { }
      // explicit inline idotprecision(const double &a, const double &b) : inf(a), sup(b) { }
      explicit inline idotprecision(const real & a) : inf(a), sup(a) { }
      explicit inline idotprecision(const real & a,const real & b) : inf(a), sup(b) { }
      explicit inline idotprecision(const dotprecision &r) : inf(r), sup(r)  { }      
      explicit        idotprecision(const l_real &) throw();     // In l_real.cpp
      explicit        idotprecision(const l_real &,const l_real &); // in l_real.cpp
      explicit        idotprecision(const l_interval &) throw(); // In l_interv.cpp

      
      // inline idotprecision& operator= (const double& a)       { inf=sup=a; return *this; }
      inline idotprecision& operator= (const real& a)         { inf=sup=a; return *this; }
      inline idotprecision& operator= (const interval& a)     { inf=Inf(a); sup=Sup(a); return *this; }
      // inline idotprecision& operator= (const int& a)          { inf=sup=a; return *this; }
      inline idotprecision& operator= (const dotprecision& a) { inf=sup=a; return *this; }
      inline idotprecision& operator= (const idotprecision& a){ inf=a.inf; sup=a.sup; return *this; }
      inline idotprecision& operator= (const l_real & a)      { inf=sup=a; return *this; }
             idotprecision& operator= (const l_interval &) throw(); // in l_interv.cpp

      // ---- Destruktor    ----
      // ~idotprecision() {} unnoetig

      // ---- Typwandlungen ----
      friend inline idotprecision _idotprecision(const real &);
      friend inline idotprecision _idotprecision(const real &,const real &);
      friend inline idotprecision _unchecked_idotprecision(const real &,const real &);
      friend inline idotprecision _idotprecision(const dotprecision&);
      friend inline idotprecision _idotprecision(const dotprecision&, const dotprecision&);
      friend inline idotprecision _unchecked_idotprecision(const dotprecision&, const dotprecision&);

      friend inline idotprecision _idotprecision(const l_real &a) throw() { return idotprecision(a); }  
      friend inline idotprecision _idotprecision(const l_real &a,const l_real &b) { return idotprecision(a,b); }


      // ---- Ausgabefunkt. ---------------------------------------
      friend std::istream& operator >> (std::istream& s, idotprecision& a)       throw();
      friend std::ostream& operator << (std::ostream& s, const idotprecision& a) throw();
      friend std::string&  operator >> (std::string&  s, idotprecision& a)       throw();
      friend std::string&  operator << (std::string&  s, const idotprecision& a) throw();
      friend void          operator >> (const std::string &s,idotprecision& a)   throw();
      friend void          operator >> (const char *s       ,idotprecision& a)   throw();

      // ---- Standardfunkt ---- (arithmetische Operatoren)
      friend     inline idotprecision operator -(const idotprecision &) throw();
      friend     inline idotprecision operator +(const idotprecision &) throw();

      friend     inline idotprecision operator +(const idotprecision &,const idotprecision &) throw();
      friend     inline idotprecision operator -(const idotprecision &,const idotprecision &) throw();
      friend     inline idotprecision operator |(const idotprecision &,const idotprecision &) throw();
      friend     inline idotprecision operator &(const idotprecision &,const idotprecision &) throw(ERROR_IDOTPRECISION_EMPTY_INTERVAL);

      friend     inline idotprecision operator +(const idotprecision &,const dotprecision &) throw();
      friend     inline idotprecision operator +(const dotprecision &,const idotprecision &) throw();
      friend     inline idotprecision operator -(const idotprecision &,const dotprecision &) throw();
      friend     inline idotprecision operator -(const dotprecision &,const idotprecision &) throw();
      friend     inline idotprecision operator |(const dotprecision &,const idotprecision &) throw();
      friend     inline idotprecision operator |(const idotprecision &,const dotprecision &) throw();
      friend     inline idotprecision operator |(const dotprecision &,const dotprecision &)  throw();
      friend     inline idotprecision operator &(const dotprecision &,const idotprecision &) throw(ERROR_IDOTPRECISION_EMPTY_INTERVAL);
      friend     inline idotprecision operator &(const idotprecision &,const dotprecision &) throw(ERROR_IDOTPRECISION_EMPTY_INTERVAL);

      friend     inline idotprecision operator +(const idotprecision &,const long &) throw();
      friend     inline idotprecision operator +(const long &,const idotprecision &) throw();
      friend     inline idotprecision operator -(const idotprecision &,const long &) throw();
      friend     inline idotprecision operator -(const long &,const idotprecision &) throw();
      friend     inline idotprecision operator |(const long &,const idotprecision &) throw();
      friend     inline idotprecision operator |(const idotprecision &,const long &) throw();
      friend     inline idotprecision operator &(const long &,const idotprecision &) throw(ERROR_IDOTPRECISION_EMPTY_INTERVAL);
      friend     inline idotprecision operator &(const idotprecision &,const long &) throw(ERROR_IDOTPRECISION_EMPTY_INTERVAL);

      friend     inline idotprecision operator +(const idotprecision &,const real &) throw();
      friend     inline idotprecision operator +(const real &,const idotprecision &) throw();
      friend     inline idotprecision operator -(const idotprecision &,const real &) throw();
      friend     inline idotprecision operator -(const real &,const idotprecision &) throw();
      friend     inline idotprecision operator |(const real &,const idotprecision &) throw();
      friend     inline idotprecision operator |(const idotprecision &,const real &) throw();
      friend     inline idotprecision operator &(const real &,const idotprecision &) throw(ERROR_IDOTPRECISION_EMPTY_INTERVAL);
      friend     inline idotprecision operator &(const idotprecision &,const real &) throw(ERROR_IDOTPRECISION_EMPTY_INTERVAL);
      
      friend            idotprecision operator +(const idotprecision &,const l_real &) throw();
      friend            idotprecision operator +(const l_real &,const idotprecision &) throw();
      friend            idotprecision operator -(const idotprecision &,const l_real &) throw();
      friend            idotprecision operator -(const l_real &,const idotprecision &) throw();
      friend            idotprecision operator |(const l_real &,const idotprecision &) throw();
      friend            idotprecision operator |(const idotprecision &,const l_real &) throw();
      friend            idotprecision operator &(const l_real &,const idotprecision &) throw(ERROR_IDOTPRECISION_EMPTY_INTERVAL);
      friend            idotprecision operator &(const idotprecision &,const l_real &) throw(ERROR_IDOTPRECISION_EMPTY_INTERVAL);

      friend     inline idotprecision operator +(const idotprecision &,const interval &) throw();
      friend     inline idotprecision operator +(const interval &,const idotprecision &) throw();
      friend     inline idotprecision operator -(const idotprecision &,const interval &) throw();
      friend     inline idotprecision operator -(const interval &,const idotprecision &) throw();
      friend     inline idotprecision operator |(const interval &,const idotprecision &) throw();
      friend     inline idotprecision operator |(const idotprecision &,const interval &) throw();
      friend     inline idotprecision operator &(const interval &,const idotprecision &) throw(ERROR_IDOTPRECISION_EMPTY_INTERVAL);
      friend     inline idotprecision operator &(const idotprecision &,const interval &) throw(ERROR_IDOTPRECISION_EMPTY_INTERVAL);

      friend     inline idotprecision & operator +=(idotprecision &,const idotprecision &) throw();
      friend     inline idotprecision & operator -=(idotprecision &,const idotprecision &) throw();
      friend     inline idotprecision & operator +=(idotprecision &,const interval &) throw();
      friend     inline idotprecision & operator -=(idotprecision &,const interval &) throw();
      friend     inline idotprecision & operator +=(idotprecision &,const real &) throw();
      friend     inline idotprecision & operator -=(idotprecision &,const real &) throw();
      friend            idotprecision & operator +=(idotprecision &,const l_real &) throw();
      friend            idotprecision & operator -=(idotprecision &,const l_real &) throw();
      friend     inline idotprecision & operator +=(idotprecision &,const l_interval &) throw();
      friend     inline idotprecision & operator -=(idotprecision &,const l_interval &) throw();
      
      friend     inline idotprecision & operator |=(idotprecision &,const idotprecision &) throw();
      friend     inline idotprecision & operator &=(idotprecision &,const idotprecision &) throw(ERROR_IDOTPRECISION_EMPTY_INTERVAL);

      friend     inline idotprecision & operator +=(idotprecision &,const dotprecision &) throw();      
      friend     inline idotprecision & operator -=(idotprecision &,const dotprecision &) throw();

      friend     inline idotprecision & operator |=(idotprecision &,const dotprecision &) throw();
      friend     inline idotprecision & operator &=(idotprecision &,const dotprecision &) throw(ERROR_IDOTPRECISION_EMPTY_INTERVAL);

//      friend     inline idotprecision & operator |=(idotprecision & i,const long & l) throw() { return i|=_dotprecision(l); }
//      friend     inline idotprecision & operator &=(idotprecision & i,const long & l) throw(ERROR_IDOTPRECISION_EMPTY_INTERVAL) { return i&=_dotprecision(l); }
      friend     inline idotprecision & operator |=(idotprecision & i,const real & l) throw() { return i|=dotprecision(l); }
      friend     inline idotprecision & operator &=(idotprecision & i,const real & l) throw(ERROR_IDOTPRECISION_EMPTY_INTERVAL) { return i&=dotprecision(l); }

      friend            idotprecision & operator |=(idotprecision & i,const l_real & l) throw(); // in l_real.cpp
      friend            idotprecision & operator &=(idotprecision & i,const l_real & l) throw(ERROR_IDOTPRECISION_EMPTY_INTERVAL); // in l_real.cpp

      friend     inline idotprecision & operator |=(idotprecision & i,const l_interval & l) throw(); // in l_interv.inl
      friend     inline idotprecision & operator &=(idotprecision & i,const l_interval & l) throw(ERROR_IDOTPRECISION_EMPTY_INTERVAL); // in l_interv.inl

      // ---- Vergleichsop. ----

      friend inline bool operator ==(const idotprecision &,const idotprecision &) throw();
      friend inline bool operator !=(const idotprecision &,const idotprecision &) throw();

      friend inline bool operator ==(const dotprecision &,const idotprecision &) throw();
      friend inline bool operator !=(const dotprecision &,const idotprecision &) throw();

      friend inline bool operator ==(const idotprecision &,const dotprecision &) throw();
      friend inline bool operator !=(const idotprecision &,const dotprecision &) throw();

      friend inline bool operator ==(const real &,const idotprecision &) throw();
      friend inline bool operator !=(const real &,const idotprecision &) throw();

      friend inline bool operator ==(const idotprecision &,const real &) throw();
      friend inline bool operator !=(const idotprecision &,const real &) throw();

      friend inline bool operator ==(const interval &,const idotprecision &) throw();
      friend inline bool operator !=(const interval &,const idotprecision &) throw();

      friend inline bool operator ==(const idotprecision &,const interval &) throw();
      friend inline bool operator !=(const idotprecision &,const interval &) throw();

      // ---- Mengenvergle. ----

      friend inline bool operator  <(const idotprecision &,const idotprecision &) throw();
      friend inline bool operator  >(const idotprecision &,const idotprecision &) throw();
      friend inline bool operator <=(const idotprecision &,const idotprecision &) throw();
      friend inline bool operator >=(const idotprecision &,const idotprecision &) throw();

      friend inline bool operator  <(const dotprecision &,const idotprecision &) throw();
      friend inline bool operator  >(const dotprecision &,const idotprecision &) throw() { return false; }
      friend inline bool operator <=(const dotprecision &,const idotprecision &) throw();
      friend inline bool operator >=(const dotprecision &,const idotprecision &) throw();

      friend inline bool operator  <(const idotprecision &,const dotprecision &) throw() { return false; }
      friend inline bool operator  >(const idotprecision &,const dotprecision &) throw();
      friend inline bool operator <=(const idotprecision &,const dotprecision &) throw();
      friend inline bool operator >=(const idotprecision &,const dotprecision &) throw();

      friend inline bool operator  <(const real &,const idotprecision &) throw();
      friend inline bool operator  >(const real &,const idotprecision &) throw() { return false; }
      friend inline bool operator <=(const real &,const idotprecision &) throw();
      friend inline bool operator >=(const real &,const idotprecision &) throw();

      friend inline bool operator  <(const idotprecision &,const real &) throw() { return false; }
      friend inline bool operator  >(const idotprecision &,const real &) throw();
      friend inline bool operator <=(const idotprecision &,const real &) throw();
      friend inline bool operator >=(const idotprecision &,const real &) throw();

      friend inline bool operator  <(const interval &,const idotprecision &) throw();
      friend inline bool operator  >(const interval &,const idotprecision &) throw();
      friend inline bool operator <=(const interval &,const idotprecision &) throw();
      friend inline bool operator >=(const interval &,const idotprecision &) throw();

      friend inline bool operator  <(const idotprecision &,const interval &) throw();
      friend inline bool operator  >(const idotprecision &,const interval &) throw();
      friend inline bool operator <=(const idotprecision &,const interval &) throw();
      friend inline bool operator >=(const idotprecision &,const interval &) throw();

      friend inline bool operator !(const idotprecision&) throw();
//                         operator void *(void) throw() { return (void *)(!*this); }
      
      // ---- Funktionen    ----
      
      friend dotprecision & Inf(idotprecision& a)  throw() { return a.inf; }
      friend dotprecision & Sup(idotprecision& a)  throw() { return a.sup; }
      friend const dotprecision & Inf(const idotprecision& a)  throw() { return a.inf; }
      friend const dotprecision & Sup(const idotprecision& a)  throw() { return a.sup; }
      
      friend inline idotprecision& SetInf (idotprecision &, const dotprecision &) throw();
      friend inline idotprecision& SetSup (idotprecision &, const dotprecision &) throw();
      friend inline idotprecision& SetInf (idotprecision &, const real &) throw();
      friend inline idotprecision& SetSup (idotprecision &, const real &) throw();
      friend inline idotprecision& UncheckedSetInf (idotprecision &, const dotprecision &) throw();
      friend inline idotprecision& UncheckedSetSup (idotprecision &, const dotprecision &) throw();
      friend inline idotprecision& UncheckedSetInf (idotprecision &, const real &) throw();
      friend inline idotprecision& UncheckedSetSup (idotprecision &, const real &) throw();

      friend inline bool IsEmpty (const idotprecision& a) throw();

      friend inline idotprecision   abs  (const idotprecision& a) throw();
      friend inline dotprecision    mid  (const idotprecision& a) throw();
      friend inline dotprecision    diam (const idotprecision& a) throw();
      
      friend void rnd(const idotprecision &,interval &) throw();
      friend interval rnd(const idotprecision &) throw();
      
      friend        void accumulate  (idotprecision&, const interval&, const interval&) throw();
      friend inline void accumulate  (idotprecision&, const interval&, const real&) throw();
      friend inline void accumulate  (idotprecision&, const real&, const interval&) throw();
      friend inline void accumulate  (idotprecision&, const real&, const real&) throw();
};

//----------------------------------------------------------------------
// global verfuegbare IDotprecision Akku's   

#define MAXIDOTAKKU     3
extern idotprecision idotakku[MAXIDOTAKKU];
  
//----------------------------------------------------------------------

} // namespace cxsc 

#include "idot.inl"

#endif 

