mirror of https://github.com/CGAL/cgal
332 lines
6.5 KiB
C++
332 lines
6.5 KiB
C++
// Copyright (c) 2005 INRIA Sophia-Antipolis (France).
|
|
// All rights reserved.
|
|
//
|
|
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
|
|
// modify it under the terms of the GNU Lesser General Public License as
|
|
// published by the Free Software Foundation; version 2.1 of the License.
|
|
// See the file LICENSE.LGPL distributed with CGAL.
|
|
//
|
|
// Licensees holding a valid commercial license may use this file in
|
|
// accordance with the commercial license agreement provided with the software.
|
|
//
|
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
//
|
|
// $Source$
|
|
// $Revision$ $Date$
|
|
// $Name$
|
|
//
|
|
// Author(s) : Sylvain Pion
|
|
|
|
#ifndef CGAL_UNCERTAIN_H
|
|
#define CGAL_UNCERTAIN_H
|
|
|
|
#include <CGAL/basic.h>
|
|
#include <stdexcept>
|
|
#include <CGAL/enum.h>
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
namespace CGALi {
|
|
|
|
// Accessory traits class to provide min and max value of a type.
|
|
// Specialized for bool and CGAL's enums.
|
|
template < typename T >
|
|
struct Minmax_traits;
|
|
|
|
template <>
|
|
struct Minmax_traits <bool>
|
|
{
|
|
static const bool min = false;
|
|
static const bool max = true;
|
|
};
|
|
|
|
template <>
|
|
struct Minmax_traits <Sign>
|
|
{
|
|
static const Sign min = NEGATIVE;
|
|
static const Sign max = POSITIVE;
|
|
};
|
|
|
|
template <>
|
|
struct Minmax_traits <Comparison_result>
|
|
{
|
|
static const Comparison_result min = SMALLER;
|
|
static const Comparison_result max = LARGER;
|
|
};
|
|
|
|
template <>
|
|
struct Minmax_traits <Oriented_side>
|
|
{
|
|
static const Oriented_side min = ON_NEGATIVE_SIDE;
|
|
static const Oriented_side max = ON_POSITIVE_SIDE;
|
|
};
|
|
|
|
template <>
|
|
struct Minmax_traits <Bounded_side>
|
|
{
|
|
static const Bounded_side min = ON_UNBOUNDED_SIDE;
|
|
static const Bounded_side max = ON_BOUNDED_SIDE;
|
|
};
|
|
|
|
template <>
|
|
struct Minmax_traits <Angle>
|
|
{
|
|
static const Angle min = OBTUSE;
|
|
static const Angle max = ACUTE;
|
|
};
|
|
|
|
} // namespace CGALi
|
|
|
|
|
|
// Encodes an interval [min;max] of values of type T.
|
|
// The primary template is supposed to work for enums and bool.
|
|
|
|
template < typename T >
|
|
class Uncertain
|
|
{
|
|
T _i, _s;
|
|
|
|
static unsigned failures; // Number of conversion failures.
|
|
|
|
public:
|
|
|
|
typedef T value_type;
|
|
|
|
Uncertain()
|
|
: _i(CGALi::Minmax_traits<T>::min),
|
|
_s(CGALi::Minmax_traits<T>::max) {}
|
|
|
|
Uncertain(const T & t)
|
|
: _i(t), _s(t) {}
|
|
|
|
Uncertain(const T & i, const T & s)
|
|
: _i(i), _s(s) {}
|
|
|
|
|
|
const T & inf() const { return _i; }
|
|
const T & sup() const { return _s; }
|
|
|
|
// NB : conversion to bool might be too risky
|
|
// (boost::tribool uses something else).
|
|
operator const T &() const
|
|
{
|
|
if (_i == _s)
|
|
return _i;
|
|
//++failures;
|
|
++Uncertain<bool>::number_of_failures(); // reasonnable ?
|
|
throw std::range_error("undecidable conversion of Uncertain<T>");
|
|
}
|
|
|
|
static unsigned & number_of_failures() { return failures; }
|
|
|
|
static Uncertain indeterminate();
|
|
};
|
|
|
|
|
|
template < typename T >
|
|
unsigned
|
|
Uncertain<T>::failures = 0;
|
|
|
|
|
|
// Access functions
|
|
// ----------------
|
|
|
|
template < typename T >
|
|
inline
|
|
const T & inf(Uncertain<T> const& i)
|
|
{
|
|
return i.inf();
|
|
}
|
|
|
|
template < typename T >
|
|
inline
|
|
const T & sup(Uncertain<T> const& i)
|
|
{
|
|
return i.sup();
|
|
}
|
|
|
|
|
|
// Basic functions
|
|
// ---------------
|
|
|
|
template < typename T >
|
|
inline
|
|
Uncertain<T>
|
|
Uncertain<T>::indeterminate()
|
|
{
|
|
return Uncertain<T>();
|
|
}
|
|
|
|
template < typename T >
|
|
inline
|
|
bool is_indeterminate(T const& a)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
template < typename T >
|
|
inline
|
|
bool is_indeterminate(Uncertain<T> const& a)
|
|
{
|
|
return a.inf() != a.sup();
|
|
}
|
|
|
|
template < typename T >
|
|
inline
|
|
bool is_singleton(Uncertain<T> const& a)
|
|
{
|
|
return a.inf() == a.sup();
|
|
}
|
|
|
|
|
|
// Boolean operations for Uncertain<bool>
|
|
// --------------------------------------
|
|
|
|
inline
|
|
Uncertain<bool> operator!(Uncertain<bool> const& a)
|
|
{
|
|
return Uncertain<bool>(!a.sup(), !a.inf());
|
|
}
|
|
|
|
inline
|
|
Uncertain<bool> operator|(Uncertain<bool> const& a, Uncertain<bool> const& b)
|
|
{
|
|
return Uncertain<bool>(a.inf() || b.inf(), a.sup() || b.sup());
|
|
}
|
|
|
|
inline
|
|
Uncertain<bool> operator|(bool a, Uncertain<bool> const& b)
|
|
{
|
|
return Uncertain<bool>(a || b.inf(), a || b.sup());
|
|
}
|
|
|
|
inline
|
|
Uncertain<bool> operator|(Uncertain<bool> const& a, bool b)
|
|
{
|
|
return Uncertain<bool>(a.inf() || b, a.sup() || b);
|
|
}
|
|
|
|
inline
|
|
Uncertain<bool> operator&(Uncertain<bool> const& a, Uncertain<bool> const& b)
|
|
{
|
|
return Uncertain<bool>(a.inf() && b.inf(), a.sup() && b.sup());
|
|
}
|
|
|
|
inline
|
|
Uncertain<bool> operator&(bool a, Uncertain<bool> const& b)
|
|
{
|
|
return Uncertain<bool>(a && b.inf(), a && b.sup());
|
|
}
|
|
|
|
inline
|
|
Uncertain<bool> operator&(Uncertain<bool> const& a, bool b)
|
|
{
|
|
return Uncertain<bool>(a.inf() && b, a.sup() && b);
|
|
}
|
|
|
|
|
|
// Equality operators
|
|
|
|
template < typename T >
|
|
inline
|
|
Uncertain<bool> operator==(Uncertain<T> const& a, Uncertain<T> const& b)
|
|
{
|
|
if (is_indeterminate(a) || is_indeterminate(b))
|
|
return Uncertain<bool>::indeterminate();
|
|
return a.inf() == b.inf();
|
|
}
|
|
|
|
template < typename T >
|
|
inline
|
|
Uncertain<bool> operator==(Uncertain<T> const& a, const T & b)
|
|
{
|
|
if (is_indeterminate(a))
|
|
return Uncertain<bool>::indeterminate();
|
|
return a.inf() == b;
|
|
}
|
|
|
|
template < typename T >
|
|
inline
|
|
Uncertain<bool> operator==(const T & a, Uncertain<T> const& b)
|
|
{
|
|
if (is_indeterminate(b))
|
|
return Uncertain<bool>::indeterminate();
|
|
return a == b.inf();
|
|
}
|
|
|
|
template < typename T >
|
|
inline
|
|
Uncertain<bool> operator!=(Uncertain<T> const& a, Uncertain<T> const& b)
|
|
{
|
|
return ! (a == b);
|
|
}
|
|
|
|
template < typename T >
|
|
inline
|
|
Uncertain<bool> operator!=(Uncertain<T> const& a, const T & b)
|
|
{
|
|
return ! (a == b);
|
|
}
|
|
|
|
template < typename T >
|
|
inline
|
|
Uncertain<bool> operator!=(const T & a, Uncertain<T> const& b)
|
|
{
|
|
return ! (a == b);
|
|
}
|
|
|
|
|
|
// Maker function (a la std::make_pair).
|
|
|
|
template < typename T >
|
|
inline
|
|
Uncertain<T> make_uncertain(const T&t)
|
|
{
|
|
return Uncertain<T>(t);
|
|
}
|
|
|
|
template < typename T >
|
|
inline
|
|
const Uncertain<T> & make_uncertain(const Uncertain<T> &t)
|
|
{
|
|
return t;
|
|
}
|
|
|
|
|
|
// opposite
|
|
template < typename T >
|
|
inline
|
|
Uncertain<T> opposite(const Uncertain<T> &u)
|
|
{
|
|
return Uncertain<T>(opposite(u.sup()), opposite(u.inf()));
|
|
}
|
|
|
|
|
|
// enum_cast overload
|
|
|
|
#ifdef CGAL_CFG_MATCHING_BUG_5
|
|
|
|
template < typename T, typename U >
|
|
inline
|
|
Uncertain<T> enum_cast_bug(const Uncertain<U>& u, const T*)
|
|
{
|
|
return Uncertain<T>(static_cast<const T>(u.inf()),
|
|
static_cast<const T>(u.sup()));
|
|
}
|
|
|
|
#else
|
|
|
|
template < typename T, typename U >
|
|
inline
|
|
Uncertain<T> enum_cast(const Uncertain<U>& u)
|
|
{
|
|
return Uncertain<T>(static_cast<T>(u.inf()), static_cast<T>(u.sup()));
|
|
}
|
|
|
|
#endif
|
|
|
|
CGAL_END_NAMESPACE
|
|
|
|
#endif // CGAL_UNCERTAIN_H
|