mirror of https://github.com/CGAL/cgal
372 lines
11 KiB
C++
372 lines
11 KiB
C++
// Sylvain Pion, 2008.
|
|
|
|
#include <CGAL/Uncertain.h>
|
|
#include <cassert>
|
|
#include <iostream>
|
|
#include <CGAL/enum.h>
|
|
#include <CGAL/exceptions.h>
|
|
#include <CGAL/use.h>
|
|
|
|
// The assert() macro, e.g. on Leopard, requires an int (due to the use of builtin_expect()).
|
|
// So I cast to bool manually (needed when the automatic conversion is switched off).
|
|
#define bool_assert(X) assert(bool(X))
|
|
|
|
|
|
|
|
// 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 T t2 = CGAL::indeterminate<T>();
|
|
const U u = U::indeterminate();
|
|
const U uuu = CGAL::indeterminate<U>();
|
|
const U uu;
|
|
const U v = t0;
|
|
U w = U (T(), T());
|
|
U v2 = u;
|
|
CGAL_USE(v2);
|
|
w = (w = t0);
|
|
|
|
// Various functions
|
|
t = u.inf();
|
|
t = u.sup();
|
|
|
|
bool_assert(! u.is_certain());
|
|
bool_assert( uu.is_certain());
|
|
bool_assert( v.is_certain());
|
|
bool_assert(t0 == v.make_certain());
|
|
|
|
#ifndef CGAL_NO_UNCERTAIN_CONVERSION_OPERATOR
|
|
T conv = v;
|
|
bool_assert(conv == t0);
|
|
#endif
|
|
|
|
U indet = U::indeterminate();
|
|
CGAL_USE(indet);
|
|
|
|
t = CGAL::inf(u);
|
|
t = CGAL::sup(u);
|
|
|
|
bool_assert(! CGAL::is_certain(u));
|
|
bool_assert( CGAL::is_certain(v));
|
|
bool_assert( CGAL::is_certain(t0));
|
|
bool_assert( CGAL::is_indeterminate(u));
|
|
bool_assert( CGAL::is_indeterminate(uuu));
|
|
bool_assert(! CGAL::is_indeterminate(v));
|
|
bool_assert(! CGAL::is_indeterminate(t0));
|
|
bool_assert(t0 == CGAL::get_certain(t0));
|
|
bool_assert(t0 == CGAL::get_certain(v));
|
|
bool_assert(t0 == CGAL::make_certain(t0));
|
|
bool_assert(t0 == CGAL::make_certain(v));
|
|
|
|
// Exceptions
|
|
bool ok = true;
|
|
|
|
// It is important to let that protection with CGAL_assertion_code,
|
|
// because the following test checks that
|
|
// CGAL::get_certain(Uncertain) does throw an assertion, *but if
|
|
// CGAL_NDEBUG is set*.
|
|
// -- Laurent Rineau, 2013/03/26
|
|
CGAL_assertion_code( ok = false );
|
|
try { CGAL::get_certain(u); }
|
|
catch (CGAL::Assertion_exception&) { ok = true; }
|
|
bool_assert(ok);
|
|
|
|
ok = false;
|
|
try {
|
|
CGAL::make_certain(u);
|
|
#ifndef CGAL_NO_UNCERTAIN_CONVERSION_OPERATOR
|
|
T t = u;
|
|
CGAL_USE(t);
|
|
#endif
|
|
}
|
|
catch (CGAL::Uncertain_conversion_exception&) { ok = true; }
|
|
bool_assert(ok);
|
|
|
|
U u2 = CGAL::make_uncertain(u);
|
|
U u3 = CGAL::make_uncertain(T());
|
|
CGAL_USE(u2);
|
|
CGAL_USE(u3);
|
|
|
|
// Operators
|
|
bool_assert( v == v );
|
|
bool_assert( v == t0 );
|
|
bool_assert( t0 == v );
|
|
bool_assert( ! (v != v) );
|
|
bool_assert( ! (v != t0) );
|
|
bool_assert( ! (t0 != v) );
|
|
|
|
CGAL_USE(t);
|
|
CGAL_USE(t2);
|
|
}
|
|
|
|
|
|
// 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 = U::indeterminate();
|
|
|
|
// <, <=, >, >=
|
|
bool_assert(U(n) < U(z));
|
|
bool_assert(U(z) < U(p));
|
|
bool_assert(U(n) < z);
|
|
bool_assert(n < U(z));
|
|
bool_assert(! CGAL::is_certain(indet < z));
|
|
|
|
bool_assert(U(n) <= U(z));
|
|
bool_assert(U(z) <= U(p));
|
|
bool_assert(U(z) <= U(z));
|
|
bool_assert(U(n) <= z);
|
|
bool_assert(U(n) <= n);
|
|
bool_assert(n <= U(z));
|
|
bool_assert(z <= U(z));
|
|
bool_assert(! CGAL::is_certain(indet <= z));
|
|
bool_assert(! CGAL::is_certain(indet <= indet));
|
|
|
|
bool_assert(U(z) > U(n));
|
|
bool_assert(U(p) > U(z));
|
|
bool_assert(U(z) > n);
|
|
bool_assert(z > U(n));
|
|
bool_assert(! CGAL::is_certain(z > indet));
|
|
|
|
bool_assert(U(z) >= U(n));
|
|
bool_assert(U(p) >= U(z));
|
|
bool_assert(U(z) >= U(z));
|
|
bool_assert(U(z) >= n);
|
|
bool_assert(U(n) >= n);
|
|
bool_assert(z >= U(n));
|
|
bool_assert(z >= U(z));
|
|
bool_assert(! CGAL::is_certain(z >= indet));
|
|
bool_assert(! CGAL::is_certain(indet >= indet));
|
|
|
|
bool_assert(-p == n);
|
|
bool_assert(-n == p);
|
|
bool_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 = U::indeterminate();
|
|
|
|
bool_assert(n*z == z);
|
|
bool_assert(z*n == z);
|
|
bool_assert(z*z == z);
|
|
bool_assert(p*z == z);
|
|
bool_assert(z*p == z);
|
|
bool_assert(n*n == p);
|
|
bool_assert(p*p == p);
|
|
bool_assert(n*p == n);
|
|
bool_assert(indet*z == z);
|
|
bool_assert(z*indet == z);
|
|
bool_assert(CGAL::is_indeterminate(p*indet));
|
|
bool_assert(CGAL::is_indeterminate(n*indet));
|
|
}
|
|
|
|
|
|
template <typename T>
|
|
void error_on_bool(T) {}
|
|
|
|
void error_on_bool(bool) { abort(); }
|
|
|
|
|
|
// 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 = U::indeterminate();
|
|
|
|
bool_assert(utrue);
|
|
bool_assert(!ufalse);
|
|
bool_assert(ufalse == !utrue);
|
|
bool_assert(utrue != !utrue);
|
|
bool_assert(false == !utrue);
|
|
bool_assert(true != !utrue);
|
|
|
|
bool_assert(utrue | utrue);
|
|
bool_assert(utrue | ufalse);
|
|
bool_assert(ufalse | utrue);
|
|
bool_assert(! (ufalse | ufalse));
|
|
bool_assert(utrue | true);
|
|
bool_assert(utrue | false);
|
|
bool_assert(ufalse | true);
|
|
bool_assert(! (ufalse | false));
|
|
bool_assert(true | utrue);
|
|
bool_assert(true | ufalse);
|
|
bool_assert(false | utrue);
|
|
bool_assert(! (false | ufalse));
|
|
|
|
bool_assert(utrue & utrue);
|
|
bool_assert(! (utrue & ufalse));
|
|
bool_assert(! (ufalse & utrue));
|
|
bool_assert(! (ufalse & ufalse));
|
|
bool_assert(utrue & true);
|
|
bool_assert(! (utrue & false));
|
|
bool_assert(! (ufalse & true));
|
|
bool_assert(! (ufalse & false));
|
|
bool_assert(true & utrue);
|
|
bool_assert(! (true & ufalse));
|
|
bool_assert(! (false & utrue));
|
|
bool_assert(! (false & ufalse));
|
|
|
|
bool_assert(!CGAL_AND(true, false));
|
|
bool_assert(!CGAL_AND(false, true));
|
|
bool_assert(CGAL_AND(true, true));
|
|
bool_assert(!CGAL_AND(false, false));
|
|
bool_assert(!CGAL_AND(utrue, ufalse));
|
|
bool_assert(!CGAL_AND(ufalse, utrue));
|
|
bool_assert(CGAL_AND(utrue, utrue));
|
|
bool_assert(!CGAL_AND(ufalse, ufalse));
|
|
|
|
bool_assert(CGAL_AND_3(true, true, true));
|
|
bool_assert(!CGAL_AND_3(true, false, true));
|
|
|
|
bool_assert(CGAL_OR(true, false));
|
|
bool_assert(CGAL_OR(false, true));
|
|
bool_assert(CGAL_OR(true, true));
|
|
bool_assert(!CGAL_OR(false, false));
|
|
bool_assert(CGAL_OR(utrue, ufalse));
|
|
bool_assert(CGAL_OR(ufalse, utrue));
|
|
bool_assert(CGAL_OR(utrue, utrue));
|
|
bool_assert(!CGAL_OR(ufalse, ufalse));
|
|
|
|
bool_assert(CGAL_OR_3(false, false, true));
|
|
bool_assert(!CGAL_OR_3(false, false, false));
|
|
|
|
try {
|
|
bool_assert( CGAL_AND(utrue, utrue));
|
|
bool_assert(!CGAL_AND(ufalse, ufalse));
|
|
bool_assert(!CGAL_AND(ufalse, utrue));
|
|
bool_assert(!CGAL_AND(utrue, ufalse));
|
|
bool_assert(indet.is_same(CGAL_AND(indet, indet)));
|
|
bool_assert(indet.is_same(CGAL_AND(utrue, indet)));
|
|
bool_assert(indet.is_same(CGAL_AND(indet, utrue)));
|
|
bool_assert(!CGAL_AND(ufalse, indet));
|
|
bool_assert(!CGAL_AND(indet, ufalse));
|
|
|
|
bool_assert( CGAL_OR(utrue, utrue));
|
|
bool_assert(!CGAL_OR(ufalse, ufalse));
|
|
bool_assert( CGAL_OR(ufalse, utrue));
|
|
bool_assert( CGAL_OR(utrue, ufalse));
|
|
bool_assert(indet.is_same(CGAL_OR(indet, indet)));
|
|
bool_assert( CGAL_OR(utrue, indet));
|
|
bool_assert( CGAL_OR(indet, utrue));
|
|
bool_assert(indet.is_same(CGAL_OR(ufalse, indet)));
|
|
bool_assert(indet.is_same(CGAL_OR(indet, ufalse)));
|
|
|
|
} catch (CGAL::Uncertain_conversion_exception&) {
|
|
#ifndef CGAL_CFG_NO_STATEMENT_EXPRESSIONS
|
|
std::abort();
|
|
#endif
|
|
}
|
|
|
|
// Test exceptions
|
|
bool ok = false;
|
|
try { bool b = indet; CGAL_USE(b); }
|
|
catch (CGAL::Uncertain_conversion_exception&) { ok = true; }
|
|
bool_assert(ok);
|
|
// The following must throw.
|
|
ok = false;
|
|
try { U u = indet && utrue; u = indet || ufalse; }
|
|
catch (CGAL::Uncertain_conversion_exception&) { ok = true; }
|
|
bool_assert(ok);
|
|
// The following must not throw.
|
|
try { bool b = utrue; b = ufalse; CGAL_USE(b); }
|
|
catch (CGAL::Uncertain_conversion_exception&) { bool_assert(false); }
|
|
|
|
// certainly, possibly
|
|
bool_assert(CGAL::certainly(true));
|
|
bool_assert(CGAL::certainly(utrue));
|
|
bool_assert(!CGAL::certainly(indet));
|
|
bool_assert(!CGAL::certainly(false));
|
|
bool_assert(!CGAL::certainly(ufalse));
|
|
|
|
bool_assert(CGAL::possibly(true));
|
|
bool_assert(CGAL::possibly(utrue));
|
|
bool_assert(CGAL::possibly(indet));
|
|
bool_assert(!CGAL::possibly(false));
|
|
bool_assert(!CGAL::possibly(ufalse));
|
|
|
|
bool_assert(!CGAL::certainly_not(true));
|
|
bool_assert(!CGAL::certainly_not(utrue));
|
|
bool_assert(!CGAL::certainly_not(indet));
|
|
bool_assert(CGAL::certainly_not(false));
|
|
bool_assert(CGAL::certainly_not(ufalse));
|
|
|
|
bool_assert(!CGAL::possibly_not(true));
|
|
bool_assert(!CGAL::possibly_not(utrue));
|
|
bool_assert(CGAL::possibly_not(indet));
|
|
bool_assert(CGAL::possibly_not(false));
|
|
bool_assert(CGAL::possibly_not(ufalse));
|
|
|
|
// conversion
|
|
error_on_bool(0 ? CGAL::make_uncertain(true) : indet);
|
|
// error_on_bool(0 ? true : indet); // fails due to the 2 possible conversions
|
|
}
|
|
|
|
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);
|
|
CGAL_USE(a);
|
|
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;
|
|
}
|