/*
**  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: l_interv.hpp,v 1.3 2001/08/09 11:37:56 cxsc Exp $ */

#ifndef LONG_INTERVAL_H_INCLUDED
#define LONG_INTERVAL_H_INCLUDED

#include <iostream>
#include <string>
#include "real.hpp"
#include "interval.hpp"
#include "l_real.hpp"
#include "except.hpp"
#include "idot.hpp"

namespace cxsc {

class l_interval_Inf;
class l_interval_Sup;

class l_interval
{
      friend class l_interval_Inf;
      friend class l_interval_Sup;
   
   private:
      // ---- Datenelemente ---------------------------------------

         // die eigentliche Datenstruktur
         // ein l_interval der Praezision n besteht aus n+1 reals , wobei die reals
         // 1..n das inf,
         // 1..n-1,n+1 das sup darstellen!
         // Ein echtes interval liegt also nur in den letzten beiden reals vor!
      int prec;
      real *data;
  

   public:
      // ---- Konstruktoren ---------------------------------------
#if (IndCheck)
      inline l_interval()                              throw(ERROR_LINTERVAL_WRONG_STAGPREC);
      inline l_interval(const l_interval &)            throw(ERROR_LINTERVAL_WRONG_STAGPREC); 

             l_interval(const l_real &, const l_real &) throw(ERROR_LINTERVAL_WRONG_STAGPREC,ERROR_LINTERVAL_EMPTY_INTERVAL);
             l_interval(const real &, const l_real &)   throw(ERROR_LINTERVAL_WRONG_STAGPREC,ERROR_LINTERVAL_EMPTY_INTERVAL);
             l_interval(const l_real &, const real &)   throw(ERROR_LINTERVAL_WRONG_STAGPREC,ERROR_LINTERVAL_EMPTY_INTERVAL);
      inline l_interval(const real &, const real &)     throw(ERROR_LINTERVAL_WRONG_STAGPREC,ERROR_LINTERVAL_EMPTY_INTERVAL);

      explicit        l_interval(const dotprecision &) throw(ERROR_LINTERVAL_WRONG_STAGPREC);
      explicit        l_interval(const dotprecision &,const dotprecision &) throw(ERROR_LINTERVAL_WRONG_STAGPREC,ERROR_LINTERVAL_EMPTY_INTERVAL);
      explicit        l_interval(const idotprecision &) throw(ERROR_LINTERVAL_WRONG_STAGPREC);
#else
      inline l_interval()                              throw();
      inline l_interval(const l_interval &)            throw(); 

      l_interval(const l_real &, const l_real &) throw(ERROR_LINTERVAL_EMPTY_INTERVAL);
      l_interval(const real &, const l_real &)   throw(ERROR_LINTERVAL_EMPTY_INTERVAL);
      l_interval(const l_real &, const real &)   throw(ERROR_LINTERVAL_EMPTY_INTERVAL);
      l_interval(const real &, const real &)     throw(ERROR_LINTERVAL_EMPTY_INTERVAL);

      explicit        l_interval(const dotprecision &) throw();
      explicit        l_interval(const dotprecision &,const dotprecision &) throw(ERROR_LINTERVAL_EMPTY_INTERVAL);
      explicit        l_interval(const idotprecision &) throw();
#endif 

      explicit inline l_interval(const real &) throw();
      explicit inline l_interval(const l_real &) throw();

#if(IndCheck)
      explicit INLINE l_interval(const l_ivector &) throw(ERROR_LIVECTOR_TYPE_CAST_OF_THICK_OBJ,ERROR_LIVECTOR_USE_OF_UNINITIALIZED_OBJ);      
      explicit INLINE l_interval(const l_ivector_slice &) throw(ERROR_LIVECTOR_TYPE_CAST_OF_THICK_OBJ,ERROR_LIVECTOR_USE_OF_UNINITIALIZED_OBJ);      
      explicit INLINE l_interval(const l_imatrix &m) throw(ERROR_LIMATRIX_TYPE_CAST_OF_THICK_OBJ,ERROR_LIMATRIX_USE_OF_UNINITIALIZED_OBJ);
      explicit INLINE l_interval(const l_imatrix_slice &m) throw(ERROR_LIMATRIX_TYPE_CAST_OF_THICK_OBJ,ERROR_LIMATRIX_USE_OF_UNINITIALIZED_OBJ);
      friend INLINE interval _l_interval(const l_ivector &) throw(ERROR_LIVECTOR_TYPE_CAST_OF_THICK_OBJ,ERROR_LIVECTOR_USE_OF_UNINITIALIZED_OBJ);      
      friend INLINE interval _l_interval(const l_ivector_slice &) throw(ERROR_LIVECTOR_TYPE_CAST_OF_THICK_OBJ,ERROR_LIVECTOR_USE_OF_UNINITIALIZED_OBJ);      
      friend INLINE interval _l_interval(const l_imatrix &m) throw(ERROR_LIMATRIX_TYPE_CAST_OF_THICK_OBJ,ERROR_LIMATRIX_USE_OF_UNINITIALIZED_OBJ);
      friend INLINE interval _l_interval(const l_imatrix_slice &m) throw(ERROR_LIMATRIX_TYPE_CAST_OF_THICK_OBJ,ERROR_LIMATRIX_USE_OF_UNINITIALIZED_OBJ);
#else
      explicit INLINE l_interval(const l_ivector &) throw();
      explicit INLINE l_interval(const l_ivector_slice &) throw();
      explicit INLINE l_interval(const l_imatrix &m) throw();
      explicit INLINE l_interval(const l_imatrix_slice &m) throw();
      friend INLINE interval _l_interval(const l_ivector &) throw();
      friend INLINE interval _l_interval(const l_ivector_slice &) throw();
      friend INLINE interval _l_interval(const l_imatrix &m) throw();
      friend INLINE interval _l_interval(const l_imatrix_slice &m) throw();
#endif



      inline l_interval & operator= (const real & a)    throw();
      inline l_interval & operator= (const l_real &a)  throw();
      inline l_interval & operator= (const interval & a)throw();
             l_interval & operator= (const l_interval &a)throw();
#if (IndCheck)
             l_interval & operator= (const dotprecision &a) throw(ERROR_LINTERVAL_WRONG_STAGPREC);
             l_interval & operator= (const idotprecision &) throw(ERROR_LINTERVAL_WRONG_STAGPREC);
#else
             l_interval & operator= (const dotprecision &a) throw();
             l_interval & operator= (const idotprecision &) throw();
#endif             

      // ---- Destruktor    ----
      inline ~l_interval() throw();

      // ---- Typwandlungen ----
      explicit inline l_interval(const interval &) throw();

      friend        interval::interval(const l_interval &) throw();
      friend        interval _interval(const l_interval &) throw();
      friend interval & interval::operator =(const l_interval &) throw();
            
      friend inline interval _interval(const real &, const l_real &) throw(); // Sollte in l_real!!!
      friend inline interval _interval(const l_real &, const real &) throw();
      friend inline interval _interval(const l_real &) throw();
      friend        interval _unchecked_interval(const l_real &, const l_real &) throw();

      friend inline l_interval _l_interval(const real & a) throw() { return l_interval(a); }
      friend inline l_interval _l_interval(const real & a, const real & b) throw(ERROR_LINTERVAL_EMPTY_INTERVAL) { return l_interval(a,b); }
      friend inline l_interval _l_interval(const l_real & a) throw() { return l_interval(a); }
      friend inline l_interval _l_interval(const l_real & a,const l_real & b) throw(ERROR_LINTERVAL_EMPTY_INTERVAL) { return l_interval(a,b); }
      friend inline l_interval _l_interval(const real & a, const l_real & b) throw(ERROR_LINTERVAL_EMPTY_INTERVAL) { return l_interval(a,b); }
      friend inline l_interval _l_interval(const l_real & a, const real & b) throw(ERROR_LINTERVAL_EMPTY_INTERVAL) { return l_interval(a,b); }

      friend inline l_interval _l_interval(const interval & a) throw() { return l_interval(a); }
      friend inline l_interval _l_interval(const dotprecision & a) throw() { return l_interval(a); }
      friend inline l_interval _l_interval(const dotprecision & a,const dotprecision & b) throw(ERROR_LINTERVAL_EMPTY_INTERVAL) { return l_interval(a,b); }
      friend inline l_interval _l_interval(const idotprecision & a) throw() { return l_interval(a); }

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

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

      // LI-LI
      friend l_interval operator +(const l_interval &,const l_interval &) throw();
      friend l_interval operator -(const l_interval &,const l_interval &) throw();
      friend l_interval operator *(const l_interval &,const l_interval &) throw();
      friend l_interval operator /(const l_interval &,const l_interval &) throw(ERROR_LINTERVAL_DIV_BY_ZERO);
      friend inline l_interval operator |(const l_interval &,const l_interval &) throw(ERROR_LINTERVAL_IN_EXACT_CH_OR_IS);
      friend inline l_interval operator &(const l_interval &,const l_interval &) throw(ERROR_LINTERVAL_EMPTY_INTERVAL,ERROR_LINTERVAL_IN_EXACT_CH_OR_IS);

      friend inline l_interval & operator +=(l_interval &,const l_interval &) throw();
      friend inline l_interval & operator -=(l_interval &,const l_interval &) throw();
      friend inline l_interval & operator *=(l_interval &,const l_interval &) throw();
      friend inline l_interval & operator /=(l_interval &,const l_interval &) throw();
      friend inline l_interval & operator |=(l_interval &,const l_interval &) throw();
      friend inline l_interval & operator &=(l_interval &,const l_interval &) throw(ERROR_LINTERVAL_EMPTY_INTERVAL);

      // LI-ID
      friend inline idotprecision operator +(const l_interval &,const idotprecision &) throw();
      friend inline idotprecision operator +(const idotprecision &,const l_interval &) throw();
      friend inline idotprecision operator -(const l_interval &,const idotprecision &) throw();
      friend inline idotprecision operator -(const idotprecision &,const l_interval &) throw();
      friend inline idotprecision operator |(const idotprecision &,const l_interval &) throw();
      friend inline idotprecision operator |(const l_interval &,const idotprecision &) throw();
      friend inline idotprecision operator &(const idotprecision &,const l_interval &) throw(ERROR_LINTERVAL_EMPTY_INTERVAL);
      friend inline idotprecision operator &(const l_interval &,const idotprecision &) throw(ERROR_LINTERVAL_EMPTY_INTERVAL);

      friend inline l_interval & operator |=(l_interval &,const idotprecision &) throw();
      friend inline l_interval & operator &=(l_interval &,const idotprecision &) throw(ERROR_LINTERVAL_EMPTY_INTERVAL);
 
      // LI-LR
      friend inline l_interval operator +(const l_interval &,const l_real &) throw();
      friend inline l_interval operator +(const l_real &,const l_interval &) throw();
      friend inline l_interval operator -(const l_interval &,const l_real &) throw();
      friend inline l_interval operator -(const l_real &,const l_interval &) throw();
      friend inline l_interval operator *(const l_interval &,const l_real &) throw();
      friend inline l_interval operator *(const l_real &,const l_interval &) throw();
      friend inline l_interval operator /(const l_interval &,const l_real &) throw();
      friend inline l_interval operator /(const l_real &,const l_interval &) throw();
      friend inline l_interval operator |(const l_real &,const l_interval &) throw();
      friend inline l_interval operator |(const l_interval &,const l_real &) throw();
      friend inline l_interval operator |(const l_real &,const l_real &)     throw();
      friend inline l_interval operator &(const l_real &,const l_interval &) throw(ERROR_LINTERVAL_EMPTY_INTERVAL);
      friend inline l_interval operator &(const l_interval &,const l_real &) throw(ERROR_LINTERVAL_EMPTY_INTERVAL);

      friend inline l_interval & operator +=(l_interval &,const l_real &) throw();      
      friend inline l_interval & operator -=(l_interval &,const l_real &) throw();
      friend inline l_interval & operator *=(l_interval &,const l_real &) throw();              
      friend inline l_interval & operator /=(l_interval &,const l_real &) throw(); 
      friend inline l_interval & operator |=(l_interval &,const l_real &) throw();
      friend inline l_interval & operator &=(l_interval &,const l_real &) throw(ERROR_LINTERVAL_EMPTY_INTERVAL);
 
      // LI-I
      friend inline l_interval operator +(const l_interval &,const interval &) throw();
      friend inline l_interval operator +(const interval &,const l_interval &) throw();
      friend inline l_interval operator -(const l_interval &,const interval &) throw();
      friend inline l_interval operator -(const interval &,const l_interval &) throw();
      friend inline l_interval operator *(const l_interval &,const interval &) throw();
      friend inline l_interval operator *(const interval &,const l_interval &) throw();
      friend inline l_interval operator /(const l_interval &,const interval &) throw();
      friend inline l_interval operator /(const interval &,const l_interval &) throw();
      friend inline l_interval operator |(const interval &,const l_interval &) throw();
      friend inline l_interval operator |(const l_interval &,const interval &) throw();
      friend inline l_interval operator &(const interval &,const l_interval &) throw(ERROR_LINTERVAL_EMPTY_INTERVAL);
      friend inline l_interval operator &(const l_interval &,const interval &) throw(ERROR_LINTERVAL_EMPTY_INTERVAL);

      friend inline l_interval & operator +=(l_interval &,const interval &) throw();      
      friend inline l_interval & operator -=(l_interval &,const interval &) throw();
      friend inline l_interval & operator *=(l_interval &,const interval &) throw();              
      friend inline l_interval & operator /=(l_interval &,const interval &) throw(); 
      friend inline l_interval & operator |=(l_interval &,const interval &) throw();
      friend inline l_interval & operator &=(l_interval &,const interval &) throw(ERROR_LINTERVAL_EMPTY_INTERVAL);
 
      // LI-R
      friend inline l_interval operator +(const l_interval &,const real &) throw();
      friend inline l_interval operator +(const real &,const l_interval &) throw();
      friend inline l_interval operator -(const l_interval &,const real &) throw();
      friend inline l_interval operator -(const real &,const l_interval &) throw();
      friend inline l_interval operator *(const l_interval &,const real &) throw();
      friend inline l_interval operator *(const real &,const l_interval &) throw();
      friend inline l_interval operator /(const l_interval &,const real &) throw();
      friend inline l_interval operator /(const real &,const l_interval &) throw();
      friend inline l_interval operator |(const real &,const l_interval &) throw();
      friend inline l_interval operator |(const l_interval &,const real &) throw();
      friend inline l_interval operator &(const real &,const l_interval &) throw(ERROR_LINTERVAL_EMPTY_INTERVAL);
      friend inline l_interval operator &(const l_interval &,const real &) throw(ERROR_LINTERVAL_EMPTY_INTERVAL);

      friend inline l_interval & operator +=(l_interval &,const real &) throw();      
      friend inline l_interval & operator -=(l_interval &,const real &) throw();
      friend inline l_interval & operator *=(l_interval &,const real &) throw();              
      friend inline l_interval & operator /=(l_interval &,const real &) throw(); 
      friend inline l_interval & operator |=(l_interval &,const real &) throw();
      friend inline l_interval & operator &=(l_interval &,const real &) throw(ERROR_LINTERVAL_EMPTY_INTERVAL);

      // LR-I
      friend inline l_interval operator +(const l_real &,const interval &) throw();
      friend inline l_interval operator +(const interval &,const l_real &) throw();
      friend inline l_interval operator -(const l_real &,const interval &) throw();
      friend inline l_interval operator -(const interval &,const l_real &) throw();
      friend inline l_interval operator *(const l_real &,const interval &) throw();
      friend inline l_interval operator *(const interval &,const l_real &) throw();
      friend inline l_interval operator /(const l_real &,const interval &) throw();
      friend inline l_interval operator /(const interval &,const l_real &) throw();
      friend inline l_interval operator |(const interval &,const l_real &) throw();
      friend inline l_interval operator |(const l_real &,const interval &) throw();
      friend inline l_interval operator &(const interval &,const l_real &) throw(ERROR_LINTERVAL_EMPTY_INTERVAL);
      friend inline l_interval operator &(const l_real &,const interval &) throw(ERROR_LINTERVAL_EMPTY_INTERVAL);
 
      // ---- Vergleichsop. ----
      friend        bool operator !(const l_interval &) throw();
//                         operator void *(void) throw();

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

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

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

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

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

      friend inline bool operator ==(const dotprecision &,const l_interval &) throw();
      friend inline bool operator !=(const dotprecision &,const l_interval &) throw();
      friend inline bool operator ==(const l_interval &,const dotprecision &) throw();
      friend inline bool operator !=(const l_interval &,const dotprecision &) throw();
   
      // ---- Mengenvergle. ----
      friend        bool operator  <(const l_interval &,const l_interval &) throw();
      friend        bool operator  >(const l_interval &,const l_interval &) throw();
      friend        bool operator <=(const l_interval &,const l_interval &) throw();
      friend        bool operator >=(const l_interval &,const l_interval &) throw();

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

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

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

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

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

      // ---- Funktionen    ----
      
      friend inline l_interval_Inf Inf (l_interval &)  throw();
      friend inline l_interval_Sup Sup (l_interval &)  throw();
      friend inline l_real         Inf (const l_interval &) throw();
      friend inline l_real         Sup (const l_interval &) throw();
      
      
      friend int StagPrec(const l_interval &a) throw() { return a.prec; }

      friend inline l_interval & SetInf (l_interval & a, const l_real & b)  throw(ERROR_LINTERVAL_EMPTY_INTERVAL);
      friend inline l_interval & SetSup (l_interval & a, const l_real & b) throw(ERROR_LINTERVAL_EMPTY_INTERVAL);
      friend inline l_interval & SetInf (l_interval & a, const real & b)  throw(ERROR_LINTERVAL_EMPTY_INTERVAL);
      friend inline l_interval & SetSup (l_interval & a, const real & b) throw(ERROR_LINTERVAL_EMPTY_INTERVAL);
      friend inline l_interval  adjust (const l_interval &) throw();         

      friend inline l_interval & UncheckedSetInf (l_interval & a, const l_real & b) throw();
      friend inline l_interval & UncheckedSetSup (l_interval & a, const l_real & b) throw();
      friend inline l_interval & UncheckedSetInf (l_interval & a, const real & b) throw();
      friend inline l_interval & UncheckedSetSup (l_interval & a, const real & b) throw();
      
      friend void ConvexHull(const l_interval &, const l_interval &, l_interval &, l_interval &) throw();
      friend void Intersection(const l_interval &, const l_interval &, l_interval &, l_interval &) throw(ERROR_LINTERVAL_EMPTY_INTERVAL);
   
      friend inline l_interval abs  (const l_interval & a) throw();
      friend        l_real     mid  (const l_interval & a) throw();
      friend inline l_real     diam (const l_interval & a) throw();

      friend l_interval pow(const l_interval &, const l_interval &) throw(ERROR_LINTERVAL_STD_FKT_OUT_OF_DEF); // Pow(x,y)
      friend l_interval power(const l_interval &, int);       // Power(x,n)
      friend l_interval sqr(const l_interval &);              // Sqr(x)

      friend l_interval sqrt(const l_interval &) throw(ERROR_LINTERVAL_STD_FKT_OUT_OF_DEF);             // Sqrt(x)
      friend l_interval sqrt(const l_interval &, int) throw(ERROR_LINTERVAL_STD_FKT_OUT_OF_DEF);        // NSqrt(n,x)

      friend l_interval sin(const l_interval &) throw(ERROR_LINTERVAL_FAK_OVERFLOW);    // Sin(x)
      friend l_interval cos(const l_interval &) throw(ERROR_LINTERVAL_FAK_OVERFLOW);    // Cos(x)
      friend l_interval tan(const l_interval &) throw(ERROR_LINTERVAL_FAK_OVERFLOW,ERROR_LINTERVAL_STD_FKT_OUT_OF_DEF);    // Tan(x)
      friend l_interval cot(const l_interval &) throw(ERROR_LINTERVAL_FAK_OVERFLOW,ERROR_LINTERVAL_STD_FKT_OUT_OF_DEF);    // Cot(x)

      friend l_interval asin(const l_interval &) throw(ERROR_LINTERVAL_STD_FKT_OUT_OF_DEF);   // ASin(x)
      friend l_interval acos(const l_interval &) throw(ERROR_LINTERVAL_STD_FKT_OUT_OF_DEF);   // ACos(x)
      friend l_interval atan(const l_interval &) throw();   // ATan(x)
      friend l_interval acot(const l_interval &) throw();   // ACot(x)

      friend l_interval exp(const l_interval &) throw(ERROR_LINTERVAL_FAK_OVERFLOW);    // Exp(x)
      friend l_interval ln(const l_interval &) throw(ERROR_LINTERVAL_STD_FKT_OUT_OF_DEF);     // Ln(x)
      friend l_interval sinh(const l_interval &) throw(ERROR_LINTERVAL_FAK_OVERFLOW);   // Sinh(x)
      friend l_interval cosh(const l_interval &) throw(ERROR_LINTERVAL_FAK_OVERFLOW);   // Cosh(x)
      friend l_interval tanh(const l_interval &) throw(ERROR_LINTERVAL_FAK_OVERFLOW);   // Tanh(x)
      friend l_interval coth(const l_interval &) throw(ERROR_LINTERVAL_STD_FKT_OUT_OF_DEF,ERROR_LINTERVAL_FAK_OVERFLOW);   // Coth(x)           
 
      friend l_interval asinh(const l_interval &) throw(ERROR_LINTERVAL_STD_FKT_OUT_OF_DEF,ERROR_LINTERVAL_FAK_OVERFLOW);  // ASinh(x)
      friend l_interval acosh(const l_interval &) throw(ERROR_LINTERVAL_STD_FKT_OUT_OF_DEF,ERROR_LINTERVAL_FAK_OVERFLOW);  // ACosh(x)
      friend l_interval atanh(const l_interval &) throw(ERROR_LINTERVAL_STD_FKT_OUT_OF_DEF,ERROR_LINTERVAL_FAK_OVERFLOW);  // ATanh(x)
      friend l_interval acoth(const l_interval &) throw(ERROR_LINTERVAL_STD_FKT_OUT_OF_DEF,ERROR_LINTERVAL_FAK_OVERFLOW);  // ACoth(x)

      // Operatoren: l/real op idotprecision
      //      
      // friend inline void accumulate(idotprecision &, const real &, const l_real &) throw();
      // friend inline void accumulate(idotprecision &, const l_real &, const real &) throw();

      // Operatoren: l_real op idotprecision
      //
      // friend inline void accumulate(idotprecision &, const l_real &, const l_real &) throw();

      // Operatoren: real, l_interval op idotprecision
      //
      friend inline void accumulate(idotprecision &, const real &, const l_interval &) throw();
      friend inline void accumulate(idotprecision &, const l_interval &, const real &) throw();

      // Operatoren: interval, l_real op idotprecision
      //
      friend inline void accumulate(idotprecision &, const interval &, const l_real &) throw();
      friend inline void accumulate(idotprecision &, const l_real &, const interval &) throw();    

      // Operatoren: l_interval, l_real op idotprecision
      //
      friend inline void accumulate(idotprecision &, const l_interval &, const l_real &) throw();
      friend inline void accumulate(idotprecision &, const l_real &, const l_interval &) throw();

      // Operatoren: l_interval, interval op idotprecision
      //
      friend inline void accumulate(idotprecision &, const l_interval &, const interval &) throw();
      friend inline void accumulate(idotprecision &, const interval &, const l_interval &) throw();

      // Operatoren: l_interval op idotprecision
      //
      friend void accumulate(idotprecision &, const l_interval &, const l_interval &) throw();
      
#if (IndCheck)
      inline real & operator [](int) throw(ERROR_LINTERVAL_ELEMENT_NOT_IN_LONG);
#else
      inline real & operator [](int) throw();
#endif
            
   private:
#if (IndCheck)
      inline void _allo(int) throw(ERROR_LINTERVAL_WRONG_STAGPREC);
#else
      inline void _allo(int) throw();
#endif
      inline void _clear(int) throw();
      void _akku_out() throw();
      void _akku_out_inn() throw();
      void _akku_add(idotprecision &) const throw();
      void _akku_sub(idotprecision &) const throw();
      //void _create_l_interval(l_real &, l_real &);
      inline real & elem(int i)       { return data[i-1]; }
      inline real   elem(int i) const { return data[i-1]; }
             
};

class l_interval_Inf
{
   private:
      l_interval & my_l_interval;
   public:
      // l_interval_Inf(const l_interval_Inf &a) throw() : my_l_interval(a.my_l_interval) {}
      l_interval_Inf(l_interval &a) throw() : my_l_interval(a) {}
                   operator l_real(void) const { return Inf((const l_interval)my_l_interval); }  
      l_interval & operator =(const l_real & a) throw(ERROR_LINTERVAL_EMPTY_INTERVAL)  { SetInf(my_l_interval,a); return my_l_interval; }
      l_interval & operator =(const real & a) throw(ERROR_LINTERVAL_EMPTY_INTERVAL)    { SetInf(my_l_interval,_l_real(a)); return my_l_interval; }
      // l_interval & operator =(int a) throw(ERROR_LINTERVAL_EMPTY_INTERVAL)             { SetInf(my_l_interval,_l_real(a)); return my_l_interval; }
};

class l_interval_Sup
{
   private:
      l_interval & my_l_interval;
   public:
      l_interval_Sup(l_interval &a) throw() : my_l_interval(a) {}
                   operator l_real(void) const { return Sup((const l_interval)my_l_interval); }
      l_interval & operator =(const l_real & a) throw(ERROR_LINTERVAL_EMPTY_INTERVAL)  { SetSup(my_l_interval,a); return my_l_interval; }
      l_interval & operator =(const real & a) throw(ERROR_LINTERVAL_EMPTY_INTERVAL)    { SetSup(my_l_interval,_l_real(a)); return my_l_interval; }
      // l_interval & operator =(int a) throw(ERROR_LINTERVAL_EMPTY_INTERVAL)             { SetSup(my_l_interval,_l_real(a)); return my_l_interval; }    
};

} // namespace cxsc 

#include "l_interv.inl"


#endif

