mirror of https://github.com/CGAL/cgal
Add documentation and test-suite for CGAL::Uncertain.
Some other fixes.
This commit is contained in:
parent
2da32b8ba8
commit
9ae3ea91b7
|
|
@ -3485,9 +3485,11 @@ Ridges_3/examples/Ridges_3/skip_vcproj_auto_generation -text
|
|||
Ridges_3/test/Ridges_3/data/ellipsoid.off -text svneol=unset#application/octet-stream
|
||||
Robustness/demo/Robustness/help/index.html svneol=native#text/html
|
||||
Robustness/demo/Robustness/robustness.vcproj eol=crlf
|
||||
STL_Extension/doc_tex/STL_Extension_ref/Uncertain.tex -text
|
||||
STL_Extension/include/CGAL/Default_argument.h -text
|
||||
STL_Extension/include/CGAL/array.h -text
|
||||
STL_Extension/include/CGAL/type_traits.h -text
|
||||
STL_Extension/test/STL_Extension/test_Uncertain.cpp -text
|
||||
STL_Extension/test/STL_Extension/test_type_traits.cpp -text
|
||||
Scripts/developer_scripts/autotest_cgal_with_cmake -text
|
||||
Scripts/developer_scripts/check_no_CGAL_USE_without_includes_before -text
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ generic algorithms, iterators, functor adaptors for binding and swapping
|
|||
arguments and for composition, functors for projection and creation and
|
||||
adaptor classes around iterators and circulators. See also circulators in
|
||||
Chapter~\ref{chapterCirculators}. A class storing polymorphic objects
|
||||
is also provided.
|
||||
is also provided, as well as a class to manage the uncertainty of some values.
|
||||
|
||||
\section{Doubly-Connected List Managing Items in Place}
|
||||
|
||||
|
|
@ -112,3 +112,23 @@ It can be used by a function to return objects of different types.
|
|||
A mechanism to extract the stored object based on its type is also provided.
|
||||
This class is similar to \ccc{boost::any}.
|
||||
|
||||
\section{Uncertainty management}
|
||||
|
||||
The class \ccStyle{Uncertain<T>} represents a range of values of type \ccc{T}.
|
||||
\ccc{T} is allowed to stand for \ccc{bool}, or CGAL's enumeration types
|
||||
\ccc{Sign}, \ccc{Comparison_result}, \ccc{Orientation}, \ccc{Oriented_side},
|
||||
\ccc{Bounded_side} and \ccc{Angle}.
|
||||
|
||||
The idea is that sometimes you are not sure of the result of a function,
|
||||
and you would like to communicate that to the caller. \ccc{Uncertain<T>}
|
||||
allows just that. It also provides functions to naturally extend the
|
||||
Boolean operations for \ccc{Uncertain<bool>} for example.
|
||||
|
||||
\ccc{Uncertain<T>} is used in CGAL as the return type of geometric predicates
|
||||
when the number type used is interval arithmetic like \ccc{Interval_nt}.
|
||||
End users typically do not see it as it is hidden in the implementation
|
||||
of the filtered predicates provided by the various filtered kernels,
|
||||
but it is important that providers of predicates that are meant to be
|
||||
filtered by \ccc{Filtered_predicate}, know about it.
|
||||
|
||||
It can also be used in other contexts as well, as it is a general tool.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,326 @@
|
|||
%% =============================================================================
|
||||
%% The CGAL Reference Manual
|
||||
%% Chapter: STL Extensions - The Reference Part
|
||||
%% -----------------------------------------------------------------------------
|
||||
%% author: Sylvain Pion
|
||||
%% -----------------------------------------------------------------------------
|
||||
%% $Id: $
|
||||
%% $URL: $
|
||||
%% =============================================================================
|
||||
|
||||
%% +=========================================================================+
|
||||
|
||||
\begin{ccRefClass}{Uncertain<T>}
|
||||
|
||||
\ccDefinition
|
||||
|
||||
An object of the class \ccClassTemplateName\ represents an uncertainty on the
|
||||
value of type \ccc{T}. This uncertainty is represented by a non-empty range of
|
||||
values of type \ccc{T}.
|
||||
|
||||
The idea is that sometimes you are not sure of the result of a function, and
|
||||
you would like to communicate that to the caller. \ccc{Uncertain<T>} allows
|
||||
just that.
|
||||
|
||||
\ccc{Uncertain<T>} is also meant to be used as a drop-in replacement for
|
||||
\ccc{T} in some template contexts, as much as possible. This is why it
|
||||
provides overloaded operators and functions to naturally extend the Boolean
|
||||
operations for \ccc{Uncertain<bool>} for example, or the operations on
|
||||
enumeration types.
|
||||
|
||||
\ccc{Uncertain<T>} is used in CGAL as the return type of geometric predicates
|
||||
when the number type used is interval arithmetic like \ccc{Interval_nt}. End
|
||||
users typically do not see it, as it is hidden in the implementation of the
|
||||
filtered predicates provided by the various filtered kernels, but it is
|
||||
important that providers of predicates that are meant to be filtered by
|
||||
\ccc{Filtered_predicate}, know about it.
|
||||
|
||||
Note concerning \cgal\ assertions: assertions checking an expression of type
|
||||
\ccc{Uncertain<bool>} will trigger an assertion failure only if the assertion
|
||||
is certainly false. In case of an indeterminate value, the assertion is not
|
||||
triggered. This means that we assume, in case of doubt, that there is no
|
||||
error.
|
||||
|
||||
It can also be used in other contexts as well, as it is a general tool.
|
||||
This can be seem as support for non-deterministic programming.
|
||||
Finally, note that this class has some common points with \ccc{boost::tribool}.
|
||||
|
||||
\ccInclude{CGAL/Uncertain.h}
|
||||
|
||||
%% +-----------------------------------+
|
||||
\ccParameters
|
||||
|
||||
The parameter \ccStyle{T} can either be \ccc{bool} or one of the three-valued
|
||||
(-1, 0, 1) enumeration types: \ccc{Sign}, \ccc{Comparison_result},
|
||||
\ccc{Orientation}, \ccc{Oriented_side}, \ccc{Bounded_side} or \ccc{Angle}.
|
||||
|
||||
Some functions are defined only when \ccc{T} is \ccc{bool} or alternatively
|
||||
when it is one of the enumeration types listed previously.
|
||||
|
||||
% TODO : the CGALi::Minmax_traits should be documented (and renamed before that).
|
||||
|
||||
%% +-----------------------------------+
|
||||
\ccTypes
|
||||
\ccSetThreeColumns{static Uncertain<T>}{l.swap( l1)xxxxxxxxxxxx;}{}
|
||||
\ccPropagateThreeToTwoColumns
|
||||
|
||||
\ccNestedType{value_type}{The type \ccc{T}.}
|
||||
|
||||
\ccNestedType{Uncertain_conversion_exception}{The type of the exception
|
||||
thrown for uncertain conversions. It is a typedef to the type
|
||||
\ccc{CGAL::Uncertain_conversion_exception} which derives from \ccc{std::range_error}.}
|
||||
|
||||
%% +-----------------------------------+
|
||||
\ccCreation
|
||||
\ccCreationVariable{u}
|
||||
|
||||
\ccConstructor{Uncertain();}
|
||||
{introduces an indeterminate value.}
|
||||
|
||||
\ccConstructor{Uncertain(T t);}
|
||||
{introduces a certain object with value \ccc{t}.}
|
||||
|
||||
\ccMethod{Uncertain& operator=(T t);}
|
||||
{assigns the certain value \ccc{t} to \ccc{u}.}
|
||||
|
||||
\ccConstructor{Uncertain(T i, T s);}
|
||||
{introduces an object representing the range with lower bound \ccc{i} and
|
||||
upper bound \ccc{s}. \ccPrecond $ i<= s$. }
|
||||
|
||||
%% +-----------------------------------+
|
||||
\ccHeading{Access Functions}
|
||||
|
||||
% \def\ccTagRmTrailingConst{\ccFalse}
|
||||
\ccMethod{T inf() const;}
|
||||
{returns the lower bound of the range represented by~\ccVar.}
|
||||
|
||||
\ccGlue\ccMethod{T sup() const;}
|
||||
{returns the upper bound of the range represented by~\ccVar.}
|
||||
|
||||
%% +-----------------------------------+
|
||||
\ccHeading{Uncertainty testing and conversion}
|
||||
|
||||
\ccMethod{bool is_certain() const;}
|
||||
{returns \ccc{true} iff the value is certain, that is, it is unique, the range
|
||||
is a singleton. That is, \ccc{u.inf() == u.sup()}.}
|
||||
|
||||
\ccMethod{T make_certain() const;}
|
||||
{if \ccVar.\ccc{is_certain()}, then returns the certain value which is represented.
|
||||
Otherwise, throws an exception of type \ccc{Uncertain_conversion_exception}.}
|
||||
|
||||
\ccMethod{operator T() const;}
|
||||
{conversion operator to \ccc{T}. It does and returns the same thing as
|
||||
\ccVar.\ccc{make_certain()}. Note that relying on the automatic conversion
|
||||
can throw exceptions, which defeats the purpose of propagating uncertainty.
|
||||
Nevertheless, in many cases, it is hard to avoid it, for example for the
|
||||
\ccc{&&} and $||$ operators for \ccc{bool} (see below).}
|
||||
|
||||
%% +-----------------------------------+
|
||||
\ccHeading{Static member function}
|
||||
|
||||
\def\ccTagRmEigenClassName{\ccFalse}
|
||||
\ccFunction{static Uncertain<T> Uncertain<T>::indeterminate();}
|
||||
{returns an indeterminate range, like the default constructor.}
|
||||
|
||||
%% +-----------------------------------+
|
||||
\ccHeading{Free functions}
|
||||
|
||||
\ccFunction{template <class T> T inf(Uncertain<T> u);}
|
||||
{returns \ccc{u.inf()}.}
|
||||
|
||||
\ccFunction{template <class T> T sup(Uncertain<T> u);}
|
||||
{returns \ccc{u.sup()}.}
|
||||
|
||||
\ccFunction{template <class T> bool is_certain(T t);}
|
||||
{returns \ccc{true}.}
|
||||
|
||||
\ccFunction{template <class T> bool is_certain(Uncertain<T> u);}
|
||||
{returns \ccc{u}.\ccc{is_certain}().}
|
||||
|
||||
\ccFunction{template <class T> bool is_indeterminate(T u);}
|
||||
{returns \ccc{false}.}
|
||||
|
||||
\ccFunction{template <class T> bool is_indeterminate(Uncertain<T> u);}
|
||||
{returns \ccc{!is_certain(u)}.}
|
||||
|
||||
\ccFunction{template <class T> T get_certain(T t);}
|
||||
{returns \ccc{t}.}
|
||||
|
||||
\ccFunction{template <class T> T get_certain(Uncertain<T> u);}
|
||||
{returns \ccc{u}.\ccc{make_certain}(). \ccPrecond \ccc{u}.\ccc{is_certain}().}
|
||||
|
||||
\ccFunction{template <class T> T make_certain(T t);}
|
||||
{returns \ccc{t}.}
|
||||
|
||||
\ccFunction{template <class T> T make_certain(Uncertain<T> u);}
|
||||
{returns \ccc{u}.\ccc{make_certain}().}
|
||||
|
||||
\ccFunction{template <class T> Uncertain<T> make_uncertain(T t);}
|
||||
{returns \ccc{Uncertain<T>(u)}.}
|
||||
|
||||
\ccFunction{template <class T> Uncertain<T> make_uncertain(Uncertain<T> u);}
|
||||
{returns \ccc{u}.}
|
||||
|
||||
%% +-----------------------------------+
|
||||
\ccHeading{Overloaded operators}
|
||||
|
||||
The overloaded operators and functions are defined as preserving the set-inclusion property.
|
||||
Similarly to interval arithmetic, the returned range is guaranteed to contain
|
||||
the result of the operation over all values of the input range(s).
|
||||
In the following documentation we express this as the extension of the corresponding function
|
||||
over the type \ccc{T}.
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<bool> operator==(Uncertain<T> u, Uncertain<T> v);}
|
||||
{returns the extension of the equality operator over \ccc{u} and \ccc{v}.}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<bool> operator==(Uncertain<T> u, T v);}
|
||||
{returns \ccc{u == make_uncertain(v)}.}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<bool> operator==(T u, Uncertain<T> v);}
|
||||
{returns \ccc{v == u}.}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<bool> operator!=(Uncertain<T> u, Uncertain<T> v);}
|
||||
{returns the extension of the inequality operator over \ccc{u} and \ccc{v}.}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<bool> operator!=(Uncertain<T> u, T v);}
|
||||
{returns \ccc{u != make_uncertain(v)}.}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<bool> operator!=(T u, Uncertain<T> v);}
|
||||
{returns \ccc{v != u}.}
|
||||
|
||||
%% +-----------------------------------+
|
||||
\ccHeading{Overloaded operators for \ccc{Uncertain<bool>} only}
|
||||
|
||||
\ccFunction{Uncertain<bool> operator!(Uncertain<bool> u);}
|
||||
{returns the range containing the negated values of \ccc{u}.}
|
||||
|
||||
\ccFunction{Uncertain<bool> operator|(Uncertain<bool> u, Uncertain<bool> v);}
|
||||
{returns the range containing the values computed as logical or from \ccc{u} and \ccc{v}.}
|
||||
|
||||
\ccFunction{Uncertain<bool> operator|(Uncertain<bool> u, bool v);}
|
||||
{returns \ccc{u | make_uncertain(v)}.}
|
||||
|
||||
\ccFunction{Uncertain<bool> operator|(bool u, Uncertain<bool> v);}
|
||||
{returns \ccc{v | u}.}
|
||||
|
||||
\ccFunction{Uncertain<bool> operator&(Uncertain<bool> u, Uncertain<bool> v);}
|
||||
{returns the range containing the values computed as logical and from \ccc{u} and \ccc{v}.}
|
||||
|
||||
\ccFunction{Uncertain<bool> operator&(Uncertain<bool> u, bool v);}
|
||||
{returns \ccc{u & make_uncertain(v)}.}
|
||||
|
||||
\ccFunction{Uncertain<bool> operator&(bool u, Uncertain<bool> v);}
|
||||
{returns \ccc{v & u}.}
|
||||
|
||||
Note : the logical operators $\&\&$ and $||$ are not overloaded on purpose. The reason
|
||||
is that, when \ccc{f() && g()} is evaluated and they return \ccc{bool}, then \ccc{g()}
|
||||
is only evaluated when \ccc{f()} returns \ccc{true}. One could have a dependency so
|
||||
that \ccc{g()} has an internal precondition that implies that \ccc{f()} returns true.
|
||||
The overloaded operators for user-defined types do not provide this short-circuiting
|
||||
property, and so, if the overloaded operators where provided, then \ccc{g()} would
|
||||
be evaluated, no matter the result of \ccc{f()}, which could lead to an unwanted
|
||||
situation. The $\&$ and $|$ operators do not have this short-circuiting property,
|
||||
and are therefore overloaded safely.
|
||||
|
||||
%% +-----------------------------------+
|
||||
\ccHeading{Overloaded operators and functions for \ccc{Uncertain<enum T>} only}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<bool> operator<(Uncertain<T> u, Uncertain<T> v);}
|
||||
{returns the extension of the less-than operator over \ccc{u} and \ccc{v}.}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<bool> operator<(Uncertain<T> u, T v);}
|
||||
{returns \ccc{u < make_uncertain(v)}.}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<bool> operator<(T u, Uncertain<T> v);}
|
||||
{returns \ccc{make_uncertain(u) < v}.}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<bool> operator>(Uncertain<T> u, Uncertain<T> v);}
|
||||
{returns the extension of the greater-than operator over \ccc{u} and \ccc{v}.}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<bool> operator>(Uncertain<T> u, T v);}
|
||||
{returns \ccc{u > make_uncertain(v)}.}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<bool> operator>(T u, Uncertain<T> v);}
|
||||
{returns \ccc{make_uncertain(u) > v}.}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<bool> operator<=(Uncertain<T> u, Uncertain<T> v);}
|
||||
{returns the extension of the less-than or equal operator over \ccc{u} and \ccc{v}.}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<bool> operator<=(Uncertain<T> u, T v);}
|
||||
{returns \ccc{u <= make_uncertain(v)}.}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<bool> operator<=(T u, Uncertain<T> v);}
|
||||
{returns \ccc{make_uncertain(u) <= v}.}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<bool> operator>=(Uncertain<T> u, Uncertain<T> v);}
|
||||
{returns the extension of the greater-than or equal operator over \ccc{u} and \ccc{v}.}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<bool> operator>=(Uncertain<T> u, T v);}
|
||||
{returns \ccc{u > make_uncertain(v)}.}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<bool> operator>=(T u, Uncertain<T> v);}
|
||||
{returns \ccc{make_uncertain(u) >= v}.}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<T> operator*(Uncertain<T> u, Uncertain<T> v);}
|
||||
{returns the extension of the multiplication operator over \ccc{u} and \ccc{v}.
|
||||
This requires \ccc{T} to have a multiplication operator as well.}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<T> operator*(Uncertain<T> u, T v);}
|
||||
{returns \ccc{u * make_uncertain(v)}.}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<T> operator<(T u, Uncertain<T> v);}
|
||||
{returns \ccc{make_uncertain(u) * v}.}
|
||||
|
||||
\ccFunction{template <class T>
|
||||
Uncertain<T> operator-(Uncertain<T> u);}
|
||||
{returns the extension of the unary minus operator over \ccc{u}.}
|
||||
|
||||
\ccFunction{template <class T, class U>
|
||||
Uncertain<T> enum_cast(Uncertain<U> u);}
|
||||
{returns the extension of the \ccc{enum_cast<T>} function over \ccc{u}.}
|
||||
|
||||
%% +-----------------------------------+
|
||||
\ccHeading{Other free functions for \ccc{Uncertain<bool>}}
|
||||
|
||||
\ccFunction{bool certainly(Uncertain<bool> u);}
|
||||
{returns \ccc{true} iff \ccVar.\ccc{is_certain()}, and the \ccVar.\ccc{make_certain}()
|
||||
returns \ccc{true}.}
|
||||
|
||||
\ccFunction{bool certainly(bool u);}
|
||||
{returns \ccc{u}.}
|
||||
|
||||
\ccFunction{bool possibly(Uncertain<bool> u);}
|
||||
{returns \ccc{true} iff \ccVar.\ccc{is_certain()} returns \ccc{false}, or if
|
||||
\ccVar.\ccc{make_certain}() returns \ccc{true}.}
|
||||
|
||||
\ccFunction{bool possibly(bool u);}
|
||||
{returns \ccc{u}.}
|
||||
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{CGAL::Interval_nt<bool>}
|
||||
|
||||
\end{ccRefClass}
|
||||
|
||||
\ccParDims
|
||||
|
|
@ -113,5 +113,6 @@
|
|||
\ccRefIdfierPage{CGAL::Tag_true}\\
|
||||
\ccRefIdfierPage{CGAL::Tag_false}\\
|
||||
\ccRefIdfierPage{CGAL::Null_tag}\\
|
||||
\ccRefIdfierPage{CGAL::Null_functor}
|
||||
\ccRefIdfierPage{CGAL::Null_functor}\\
|
||||
\ccRefIdfierPage{CGAL::Uncertain<T>}
|
||||
%% EOF
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
\input{STL_Extension_ref/multiset.tex}
|
||||
\input{STL_Extension_ref/Object.tex}
|
||||
\input{STL_Extension_ref/stl_extension.tex}
|
||||
\input{STL_Extension_ref/Uncertain.tex}
|
||||
|
||||
%%\cgalColumnLayout
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#define CGAL_UNCERTAIN_H
|
||||
|
||||
#include <CGAL/config.h>
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/enum.h>
|
||||
#include <stdexcept>
|
||||
|
||||
|
|
@ -76,8 +77,8 @@ public:
|
|||
};
|
||||
|
||||
|
||||
// Encodes an interval [min;max] of values of type T.
|
||||
// The primary template is supposed to work for enums and bool.
|
||||
// Encodes a range [inf,sup] of values of type T.
|
||||
// T can be enums or bool.
|
||||
|
||||
template < typename T >
|
||||
class Uncertain
|
||||
|
|
@ -88,10 +89,10 @@ class Uncertain
|
|||
|
||||
public:
|
||||
|
||||
typedef CGAL::Uncertain_conversion_exception Uncertain_conversion_exception;
|
||||
|
||||
typedef T value_type;
|
||||
|
||||
typedef CGAL::Uncertain_conversion_exception Uncertain_conversion_exception;
|
||||
|
||||
Uncertain()
|
||||
: _i(CGALi::Minmax_traits<T>::min),
|
||||
_s(CGALi::Minmax_traits<T>::max) {}
|
||||
|
|
@ -100,12 +101,12 @@ public:
|
|||
: _i(t), _s(t) {}
|
||||
|
||||
Uncertain(T i, T s)
|
||||
: _i(i), _s(s) {}
|
||||
: _i(i), _s(s) { CGAL_precondition(i <= s); }
|
||||
|
||||
Uncertain& operator=(T t)
|
||||
{
|
||||
_i = _s = t;
|
||||
return this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T inf() const { return _i; }
|
||||
|
|
@ -173,13 +174,6 @@ T sup(Uncertain<T> i)
|
|||
}
|
||||
|
||||
|
||||
// possibly() declarations (needed as used in the assertions)
|
||||
// ----------------------------------------------------------
|
||||
|
||||
inline bool possibly(bool b);
|
||||
inline bool possibly(Uncertain<bool> c);
|
||||
|
||||
|
||||
// Basic functions
|
||||
// ---------------
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,13 @@ void postcondition_fail ( const char*, const char*, int, const char* = "");
|
|||
void warning_fail( const char*, const char*, int, const char* = "");
|
||||
|
||||
|
||||
// The following declarations are needed first, before assertions are used.
|
||||
// ---------------------------------------------------------------------
|
||||
template < typename T > class Uncertain;
|
||||
inline bool possibly(bool b);
|
||||
inline bool possibly(Uncertain<bool> c);
|
||||
|
||||
|
||||
// macro definitions
|
||||
// =================
|
||||
// assertions
|
||||
|
|
|
|||
|
|
@ -0,0 +1,268 @@
|
|||
// Sylvain Pion, 2008.
|
||||
|
||||
#include <CGAL/Uncertain.h>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <CGAL/enum.h>
|
||||
#include <CGAL/exceptions.h>
|
||||
|
||||
// "unused variable" warning killer
|
||||
template <typename T>
|
||||
void use(T) {}
|
||||
|
||||
// generic test , for both enums and bool
|
||||
template < typename T >
|
||||
void test()
|
||||
{
|
||||
std::cout << "Testing Uncertain<T>\n";
|
||||
|
||||
typedef CGAL::Uncertain<T> U;
|
||||
|
||||
// Nested types.
|
||||
typename U::value_type t = T();
|
||||
typename U::Uncertain_conversion_exception e = CGAL::Uncertain_conversion_exception("");
|
||||
|
||||
// Constructors, assignment.
|
||||
const T t0 = static_cast<T>(0);
|
||||
const U u;
|
||||
const U v = t0;
|
||||
U w = U (T(), T());
|
||||
U v2 = u;
|
||||
w = (w = t0);
|
||||
|
||||
// Various functions
|
||||
t = u.inf();
|
||||
t = u.sup();
|
||||
|
||||
assert(! u.is_certain());
|
||||
assert( v.is_certain());
|
||||
assert(t0 == v.make_certain());
|
||||
|
||||
T conv = v;
|
||||
assert(conv == t0);
|
||||
|
||||
U indet = U::indeterminate();
|
||||
|
||||
t = CGAL::inf(u);
|
||||
t = CGAL::sup(u);
|
||||
|
||||
assert(! CGAL::is_certain(u));
|
||||
assert( CGAL::is_certain(v));
|
||||
assert( CGAL::is_certain(t0));
|
||||
assert( CGAL::is_indeterminate(u));
|
||||
assert(! CGAL::is_indeterminate(v));
|
||||
assert(! CGAL::is_indeterminate(t0));
|
||||
assert(t0 == CGAL::get_certain(t0));
|
||||
assert(t0 == CGAL::get_certain(v));
|
||||
assert(t0 == CGAL::make_certain(t0));
|
||||
assert(t0 == CGAL::make_certain(v));
|
||||
|
||||
// Exceptions
|
||||
bool ok = false;
|
||||
try { CGAL::get_certain(u); }
|
||||
catch (CGAL::Assertion_exception) { ok = true; }
|
||||
assert(ok);
|
||||
ok = false;
|
||||
try { CGAL::make_certain(u); T t = u; use(t); }
|
||||
catch (CGAL::Uncertain_conversion_exception) { ok = true; }
|
||||
assert(ok);
|
||||
|
||||
U u2 = CGAL::make_uncertain(u);
|
||||
U u3 = CGAL::make_uncertain(T());
|
||||
|
||||
// Operators
|
||||
assert( v == v );
|
||||
assert( v == t0 );
|
||||
assert( t0 == v );
|
||||
assert( ! (v != v) );
|
||||
assert( ! (v != t0) );
|
||||
assert( ! (t0 != v) );
|
||||
|
||||
use(t);
|
||||
}
|
||||
|
||||
|
||||
// test only for enums
|
||||
template < typename T >
|
||||
void test_enum()
|
||||
{
|
||||
std::cout << "Testing Uncertain<enum>\n";
|
||||
|
||||
test<T>(); // generic test
|
||||
|
||||
typedef CGAL::Uncertain<T> U;
|
||||
|
||||
T n = static_cast<T>(-1);
|
||||
T z = static_cast<T>(0);
|
||||
T p = static_cast<T>(1);
|
||||
|
||||
U indet;
|
||||
|
||||
// <, <=, >, >=
|
||||
assert(U(n) < U(z));
|
||||
assert(U(z) < U(p));
|
||||
assert(U(n) < z);
|
||||
assert(n < U(z));
|
||||
assert(! CGAL::is_certain(indet < z));
|
||||
|
||||
assert(U(n) <= U(z));
|
||||
assert(U(z) <= U(p));
|
||||
assert(U(z) <= U(z));
|
||||
assert(U(n) <= z);
|
||||
assert(U(n) <= n);
|
||||
assert(n <= U(z));
|
||||
assert(z <= U(z));
|
||||
assert(! CGAL::is_certain(indet <= z));
|
||||
assert(! CGAL::is_certain(indet <= indet));
|
||||
|
||||
assert(U(z) > U(n));
|
||||
assert(U(p) > U(z));
|
||||
assert(U(z) > n);
|
||||
assert(z > U(n));
|
||||
assert(! CGAL::is_certain(z > indet));
|
||||
|
||||
assert(U(z) >= U(n));
|
||||
assert(U(p) >= U(z));
|
||||
assert(U(z) >= U(z));
|
||||
assert(U(z) >= n);
|
||||
assert(U(n) >= n);
|
||||
assert(z >= U(n));
|
||||
assert(z >= U(z));
|
||||
assert(! CGAL::is_certain(z >= indet));
|
||||
assert(! CGAL::is_certain(indet >= indet));
|
||||
|
||||
assert(-p == n);
|
||||
assert(-n == p);
|
||||
assert(-z == z);
|
||||
}
|
||||
|
||||
// test only for enums with multiplication operator
|
||||
template < typename T >
|
||||
void test_mult_enum()
|
||||
{
|
||||
std::cout << "Testing Uncertain<enum with operator*>\n";
|
||||
|
||||
test_enum<T>(); // generic enum test.
|
||||
|
||||
typedef CGAL::Uncertain<T> U;
|
||||
|
||||
T n = static_cast<T>(-1);
|
||||
T z = static_cast<T>(0);
|
||||
T p = static_cast<T>(1);
|
||||
|
||||
U indet;
|
||||
|
||||
assert(n*z == z);
|
||||
assert(z*n == z);
|
||||
assert(z*z == z);
|
||||
assert(p*z == z);
|
||||
assert(z*p == z);
|
||||
assert(n*n == p);
|
||||
assert(p*p == p);
|
||||
assert(n*p == n);
|
||||
assert(indet*z == z);
|
||||
assert(z*indet == z);
|
||||
assert(CGAL::is_indeterminate(p*indet));
|
||||
assert(CGAL::is_indeterminate(n*indet));
|
||||
}
|
||||
|
||||
|
||||
// test only for bool
|
||||
void test_bool()
|
||||
{
|
||||
std::cout << "Testing Uncertain<bool>\n";
|
||||
|
||||
test<bool>(); // generic test
|
||||
|
||||
typedef CGAL::Uncertain<bool> U;
|
||||
|
||||
U utrue = true;
|
||||
U ufalse = false;
|
||||
U indet;
|
||||
|
||||
assert(utrue);
|
||||
assert(!ufalse);
|
||||
assert(ufalse == !utrue);
|
||||
assert(utrue != !utrue);
|
||||
assert(false == !utrue);
|
||||
assert(true != !utrue);
|
||||
|
||||
assert(utrue | utrue);
|
||||
assert(utrue | ufalse);
|
||||
assert(ufalse | utrue);
|
||||
assert(! (ufalse | ufalse));
|
||||
assert(utrue | true);
|
||||
assert(utrue | false);
|
||||
assert(ufalse | true);
|
||||
assert(! (ufalse | false));
|
||||
assert(true | utrue);
|
||||
assert(true | ufalse);
|
||||
assert(false | utrue);
|
||||
assert(! (false | ufalse));
|
||||
|
||||
assert(utrue & utrue);
|
||||
assert(! (utrue & ufalse));
|
||||
assert(! (ufalse & utrue));
|
||||
assert(! (ufalse & ufalse));
|
||||
assert(utrue & true);
|
||||
assert(! (utrue & false));
|
||||
assert(! (ufalse & true));
|
||||
assert(! (ufalse & false));
|
||||
assert(true & utrue);
|
||||
assert(! (true & ufalse));
|
||||
assert(! (false & utrue));
|
||||
assert(! (false & ufalse));
|
||||
|
||||
// Test exceptions
|
||||
bool ok = false;
|
||||
try { bool b = indet; use(b); }
|
||||
catch (CGAL::Uncertain_conversion_exception) { ok = true; }
|
||||
assert(ok);
|
||||
// The following must throw.
|
||||
ok = false;
|
||||
try { U u = indet && utrue; u = indet || ufalse; }
|
||||
catch (CGAL::Uncertain_conversion_exception) { ok = true; }
|
||||
assert(ok);
|
||||
// The following must not throw.
|
||||
try { bool b = utrue; b = ufalse; }
|
||||
catch (CGAL::Uncertain_conversion_exception) { assert(false); }
|
||||
|
||||
// certainly, possibly
|
||||
assert(CGAL::certainly(true));
|
||||
assert(CGAL::certainly(utrue));
|
||||
assert(!CGAL::certainly(indet));
|
||||
assert(!CGAL::certainly(false));
|
||||
assert(!CGAL::certainly(ufalse));
|
||||
|
||||
assert(CGAL::possibly(true));
|
||||
assert(CGAL::possibly(utrue));
|
||||
assert(CGAL::possibly(indet));
|
||||
assert(!CGAL::possibly(false));
|
||||
assert(!CGAL::possibly(ufalse));
|
||||
}
|
||||
|
||||
void test_enum_cast()
|
||||
{
|
||||
typedef CGAL::Uncertain<CGAL::Sign> Us;
|
||||
typedef CGAL::Uncertain<CGAL::Bounded_side> Ub;
|
||||
typedef CGAL::Uncertain<CGAL::Angle> Ua;
|
||||
|
||||
Us s;
|
||||
Ub b = CGAL::enum_cast<CGAL::Bounded_side>(s);
|
||||
Ua a = CGAL::enum_cast<CGAL::Angle>(s);
|
||||
s = CGAL::enum_cast<CGAL::Sign>(b);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_bool();
|
||||
test_mult_enum<CGAL::Sign>();
|
||||
test_mult_enum<CGAL::Comparison_result>();
|
||||
test_mult_enum<CGAL::Orientation>();
|
||||
test_mult_enum<CGAL::Oriented_side>();
|
||||
test_enum<CGAL::Bounded_side>();
|
||||
test_enum<CGAL::Angle>();
|
||||
test_enum_cast();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue