// Copyright (c) 2006-2008 Max-Planck-Institute Saarbruecken (Germany). // All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // Author(s) : Lutz Kettner // Michael Hemmer // // ============================================================================ // \brief provides test functions for the \c RealEmbeddable concept of // number types. #include #include #include #include #include //#include #include #include #define CGAL_SNAP_RET_FUNCTORS(RET) \ typedef typename RET::Abs Abs; \ typedef typename RET::Sgn Sgn; \ typedef typename RET::Is_finite Is_finite; \ typedef typename RET::Is_positive Is_positive; \ typedef typename RET::Is_negative Is_negative; \ typedef typename RET::Is_zero Is_zero; \ typedef typename RET::Compare Compare; \ typedef typename RET::To_double To_double; \ typedef typename RET::To_interval To_interval; #ifndef CGAL_TEST_REAL_EMBEDDABLE_H #define CGAL_TEST_REAL_EMBEDDABLE_H namespace CGAL { template class Test_to_double { public: void operator() (const ToDouble& to_double) { typedef typename ToDouble::argument_type Argument_type; typedef typename ToDouble::result_type Result_type; CGAL_static_assertion(( ::boost::is_same::value)); CGAL_USE_TYPE(Argument_type); CGAL_static_assertion(( ::boost::is_same::value)); CGAL_USE_TYPE(Result_type); assert(42.0 == to_double(Type(42))); } }; template class Test_to_double { public: void operator() (CGAL::Null_functor) { CGAL_error_msg("To_double functor not implemented"); } }; template class Test_to_interval { public: void operator() (const To_interval& to_interval) { typedef typename To_interval::argument_type Argument_type; typedef typename To_interval::result_type Result_type; typedef std::pair Interval_type; CGAL_static_assertion(( ::boost::is_same::value)); CGAL_USE_TYPE(Argument_type); CGAL_static_assertion(( ::boost::is_same::value)); CGAL_USE_TYPE(Result_type); CGAL_USE_TYPE(Interval_type); // assert(NiX::in(42.0,to_Interval(Type(42)))); // Instead of 'NiX::in': assert( 42.0 >= to_interval( Type(42) ).first ); assert( 42.0 <= to_interval( Type(42) ).second ); assert(to_interval(Type(42)).first > 41.99); assert(to_interval(Type(42)).second < 42.01); // test neagtive numbers as well to catch obvious sign // errors assert( -42.0 >= to_interval( -Type(42) ).first ); assert( -42.0 <= to_interval( -Type(42) ).second ); assert(to_interval(-Type(42)).first < -41.99); assert(to_interval(-Type(42)).second > -42.01); /* Type notdouble = ipower(2,60); notdouble = notdouble + Type(1); Interval test = to_Interval(notdouble); double lower = ipower(2.0,60); double upper = ipower(2.0,53); upper++; upper *= ipower(2.0,7); std::cout << lower << "," << upper << std::endl; std::cout << test.lower() << "," << test.upper() << std::endl; assert( (in(lower,test) == true) && (in(upper,test) == true) ); */ } }; template< class Type > class Test_to_interval< Type, CGAL::Null_tag> { public: void operator() (CGAL::Null_functor) { CGAL_error_msg( "To_Interval not implemented"); // ok, nothing to test } }; // Several libraries do not want to enforce the use of std::min/max // for the case that there is a special function for min/max // However, this may be a problem for template CGAL::min/max in case NT is a // CGAL type. These types have to overload CGAL::min/max. template void test_min_max(){ using std:: min BOOST_PREVENT_MACRO_SUBSTITUTION ; using std:: max BOOST_PREVENT_MACRO_SUBSTITUTION ; NT x(1),y(2); assert(min BOOST_PREVENT_MACRO_SUBSTITUTION (x,y)==NT(1)); assert(max BOOST_PREVENT_MACRO_SUBSTITUTION (x,y)==NT(2)); } //! tests if \c Type is a model for the \c RealComparable concept //! and terminates the program with an error message if not. template void test_real_embeddable() { test_min_max(); typedef CGAL::Real_embeddable_traits RET; CGAL_SNAP_RET_FUNCTORS(RET); typedef typename RET::Is_real_embeddable Is_real_embeddable; using CGAL::Tag_true; CGAL_static_assertion(( ::boost::is_same< Is_real_embeddable, Tag_true>::value)); CGAL_USE_TYPE(Is_real_embeddable); typedef typename RET::Boolean Boolean; typedef typename RET::Sign Sign; typedef typename RET::Comparison_result Comparison_result; check_result_type(Is_finite() ,Boolean()); check_result_type(Is_positive(),Boolean()); check_result_type(Is_negative(),Boolean()); check_result_type(Is_zero(),Boolean()); check_result_type(Sgn(),Sign()); check_result_type(Compare(),Comparison_result()); // test implicit interoperability with base type and proper default assert(Boolean() == bool()); assert(Sign() == CGAL::Sign()); assert(Comparison_result() == CGAL::Comparison_result()); typename RET::Compare compare; const Sgn sign = Sgn(); const Abs abs=Abs(); const Is_finite is_finite=Is_finite(); const Is_positive is_positive=Is_positive(); const Is_negative is_negative=Is_negative(); const Is_zero is_zero=Is_zero(); Type a(-2); Type b(1); Type c(0); assert( is_finite(a) ); assert( is_finite(b) ); assert( is_finite(c) ); assert( !is_positive(a) ); assert( is_positive(b) ); assert( !is_positive(c) ); assert( is_negative(a) ); assert( !is_negative(b) ); assert( !is_negative(c) ); assert( !is_zero(a) ); assert( !is_zero(b) ); assert( is_zero(c) ); assert( a < b); assert( b > a); assert( a <= b); assert( b >= a); assert( a <= a); assert( a >= a); assert( compare(a,b) == CGAL::SMALLER); assert( compare(b,a) == CGAL::LARGER); assert( compare(a,a) == CGAL::EQUAL); assert( sign(a) == CGAL::NEGATIVE); assert( sign(b) == CGAL::POSITIVE); assert( sign(c) == CGAL::ZERO); assert( sign(a) < sign(b)); assert( sign(b) > sign(a)); assert( sign(a) <= sign(b)); assert( sign(b) >= sign(a)); assert( sign(a) <= sign(a)); assert( sign(a) >= sign(a)); assert( sign(c) < sign(b)); assert( sign(b) > sign(c)); assert( sign(c) <= sign(b)); assert( sign(b) >= sign(c)); assert( sign(c) <= sign(c)); assert( sign(c) >= sign(c)); assert( sign(a) < sign(c)); assert( sign(c) > sign(a)); assert( sign(a) <= sign(c)); assert( sign(c) >= sign(a)); assert( abs(a) == Type(2)); assert( abs(b) == Type(1)); assert( abs(c) == Type(0)); // To_double -------------------------------------------------------------- const To_double to_double = To_double(); (void)to_double; Test_to_double ttd; ttd(to_double); // To_Interval ------------------------------------------------------------ const To_interval to_interval = To_interval(); (void)to_interval; Test_to_interval tti; tti(to_interval); // additional functions assert( CGAL_NTS is_finite( Type(1) ) ); assert( CGAL_NTS sign(Type(-5))==CGAL::NEGATIVE); assert( CGAL_NTS abs(Type(-5))==Type(5)); // assert(NiX::in(5.0,NiX::to_interval(Type(5)))); assert( CGAL_NTS compare(Type(-5),Type(6))==CGAL::SMALLER); assert( CGAL_NTS is_positive(Type(23)) ); assert( CGAL_NTS is_negative(Type(-23)) ); assert( CGAL_NTS is_zero( Type(0) ) ); assert( !CGAL_NTS is_zero( Type(23) ) ); } //! tests if \c Type says it is not a model for the \c RealComparable //! concept and terminates the program with an error message if it //! actually is. template void test_not_real_embeddable() { typedef CGAL::Real_embeddable_traits RET; typedef typename RET::Is_real_embeddable Is_real_embeddable; using CGAL::Tag_false; CGAL_static_assertion(( ::boost::is_same< Is_real_embeddable, Tag_false>::value)); CGAL_USE_TYPE(Is_real_embeddable); } //template //void test_rounded_log2_abs(Type zero, CGAL::Null_functor, CeilLog2Abs) { // typedef CGAL::Null_functor Null_functor; // CGAL_static_assertion(( ::boost::is_same< CeilLog2Abs, Null_functor>::value)); //} // //template //void test_rounded_log2_abs(Type zero, FloorLog2Abs fl_log, CeilLog2Abs cl_log) { // typedef CGAL::Null_functor Null_functor; // CGAL_static_assertion((!::boost::is_same< CeilLog2Abs, Null_functor>::value)); // // assert( fl_log(Type( 7)) == 2 ); // assert( cl_log(Type( 7)) == 3 ); // assert( fl_log(Type( 8)) == 3 ); // assert( cl_log(Type( 8)) == 3 ); // assert( fl_log(Type(-9)) == 3 ); // assert( cl_log(Type(-9)) == 4 ); // // assert( NiX::floor_log2_abs(Type( 64)) == 6 ); // assert( NiX::ceil_log2_abs( Type( 64)) == 6 ); // assert( NiX::floor_log2_abs(Type(-126)) == 6 ); // assert( NiX::ceil_log2_abs( Type(-126)) == 7 ); //} // // ////! tests that \c Floor_log2_abs and \c Ceil_log2_abs are ////! \c both CGAL::Null_functor or both working properly ////! (This is independent of the \c RealComparable concept) //template //void test_rounded_log2_abs() { // // typedef typename NiX::Real_embeddable_traits::Floor_log2_abs F; // typedef typename NiX::Real_embeddable_traits::Ceil_log2_abs C; // test_rounded_log2_abs(Type(0), F(), C()); //} } //namespace CGAL #endif // CGAL_TEST_REAL_COMPARABLE_H