diff --git a/Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/dependencies b/Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/dependencies index fffe4db3c74c..d885997679a9 100644 --- a/Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/dependencies +++ b/Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/dependencies @@ -2,6 +2,7 @@ Advancing_front_surface_reconstruction Algebraic_foundations Arithmetic_kernel BGL +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Algebraic_foundations/include/CGAL/Rational_traits.h b/Algebraic_foundations/include/CGAL/Rational_traits.h index a2ac5f1016c5..7fcf808e43b1 100644 --- a/Algebraic_foundations/include/CGAL/Rational_traits.h +++ b/Algebraic_foundations/include/CGAL/Rational_traits.h @@ -53,7 +53,7 @@ struct Rational_traits_base { private: typedef Fraction_traits FT; - typedef typename FT::Decompose Decomose; + typedef typename FT::Decompose Decompose; typedef typename FT::Compose Compose; public: @@ -61,13 +61,13 @@ struct Rational_traits_base RT numerator (const Rational& r) const { RT num,den; - Decomose()(r,num,den); + Decompose()(r,num,den); return num; } RT denominator (const Rational& r) const { RT num,den; - Decomose()(r,num,den); + Decompose()(r,num,den); return den; } diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Bitstream_descartes_E08_tree.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Bitstream_descartes_E08_tree.h index bf607e75f152..4cba93085a43 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Bitstream_descartes_E08_tree.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Bitstream_descartes_E08_tree.h @@ -303,7 +303,7 @@ class Convex_combinator_approx_Integer_log { Integer alpha_num = Integer(1), int log_denom = 1 ) : alpha_num_(alpha_num), beta_num_((Integer(1) << log_denom) - alpha_num), - half_((log_denom > 0) ? (Integer(1) << log_denom-1) : 0), + half_((log_denom > 0) ? Integer(Integer(1) << log_denom-1) : 0), log_denom_(log_denom) { CGAL_precondition(log_denom_ >= 0); diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Bitstream_descartes_rndl_tree.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Bitstream_descartes_rndl_tree.h index cba01cdc9116..a76e1c6cecae 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Bitstream_descartes_rndl_tree.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Bitstream_descartes_rndl_tree.h @@ -206,7 +206,7 @@ polynomial_power_to_bernstein_approx( std::vector f(n+1); polynomial_affine_transform_approx_log_denom( first, beyond, f.begin(), - upper_num - lower_num, lower_num, log_denom, + Integer(upper_num - lower_num), lower_num, log_denom, p+q, approx, log, logl ); diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Bitstream_descartes_rndl_tree_traits.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Bitstream_descartes_rndl_tree_traits.h index 155cfbffc68d..8ed8fa5ae0c1 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Bitstream_descartes_rndl_tree_traits.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Bitstream_descartes_rndl_tree_traits.h @@ -27,31 +27,10 @@ #include -#if CGAL_USE_CORE -namespace CORE { class BigInt; } -#endif - namespace CGAL { namespace internal { -#if CGAL_USE_CORE -// bugfix for CORE by Michael Kerber -// why is there a specialized function for CORE? -inline CORE::BigInt shift_integer_by(CORE::BigInt x, long shift){ - if( shift > 0 ){ - while(shift>63) { - x = (x >> 63); - shift-=63; - } - x = (x >> shift); - }else{ - // add 0 bits - x = (x << -shift); - } - return x; -} -#endif template Shiftable shift_integer_by(Shiftable x, long shift){ diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Real_embeddable_extension.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Real_embeddable_extension.h index 31e43a0f2dd0..9f06bc83383c 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Real_embeddable_extension.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Real_embeddable_extension.h @@ -327,7 +327,7 @@ class Real_embeddable_extension< CORE::BigFloat > { long operator()( CORE::BigFloat x ) const { CGAL_precondition(!CGAL::zero_in(x)); x = CGAL::abs(x); - return CORE::floorLg(x.m()-x.err())+x.exp()*CORE::CHUNK_BIT; + return CORE::floorLg(CORE::BigInt(x.m()-x.err()))+x.exp()*CORE::CHUNK_BIT; } }; @@ -337,7 +337,7 @@ class Real_embeddable_extension< CORE::BigFloat > { // (already commented out in EXACUS)... // NiX_precond(!(NiX::in_zero(x) && NiX::singleton(x))); x = CGAL::abs(x); - return CORE::ceilLg(x.m()+x.err())+x.exp()*CORE::CHUNK_BIT; + return CORE::ceilLg(CORE::BigInt(x.m()+x.err()))+x.exp()*CORE::CHUNK_BIT; } }; diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/bound_between_1.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/bound_between_1.h index ade0be4a1a59..aaf9185350f6 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/bound_between_1.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/bound_between_1.h @@ -220,7 +220,7 @@ simple_bound_between(const Algebraic_real& a, final_mantissa = final_mantissa << 1; final_mantissa++; y_log--; - x_m = x_m==0 ? 0 : x_m & ((Integer(1) << x_log) - 1); //x_m - CGAL::ipower(Integer(2),x_log); + x_m = x_m==0 ? 0 : Integer(x_m & ((Integer(1) << x_log) - 1)); //x_m - CGAL::ipower(Integer(2),x_log); x_log = x_m==0 ? -1 : CGAL::internal::floor_log2_abs(x_m); } final_mantissa = final_mantissa << 1; diff --git a/Algebraic_kernel_for_circles/package_info/Algebraic_kernel_for_circles/dependencies b/Algebraic_kernel_for_circles/package_info/Algebraic_kernel_for_circles/dependencies index 8d3b893eeb2b..2345a7f06d44 100644 --- a/Algebraic_kernel_for_circles/package_info/Algebraic_kernel_for_circles/dependencies +++ b/Algebraic_kernel_for_circles/package_info/Algebraic_kernel_for_circles/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Algebraic_kernel_for_circles Arithmetic_kernel +CGAL_Core Filtered_kernel Installation Interval_support diff --git a/Algebraic_kernel_for_spheres/package_info/Algebraic_kernel_for_spheres/dependencies b/Algebraic_kernel_for_spheres/package_info/Algebraic_kernel_for_spheres/dependencies index bfe13a407f4a..e9b3846ab795 100644 --- a/Algebraic_kernel_for_spheres/package_info/Algebraic_kernel_for_spheres/dependencies +++ b/Algebraic_kernel_for_spheres/package_info/Algebraic_kernel_for_spheres/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Algebraic_kernel_for_spheres Arithmetic_kernel +CGAL_Core Filtered_kernel Installation Interval_support diff --git a/Alpha_shapes_2/package_info/Alpha_shapes_2/dependencies b/Alpha_shapes_2/package_info/Alpha_shapes_2/dependencies index 6c1597376389..d9c0f7d94a82 100644 --- a/Alpha_shapes_2/package_info/Alpha_shapes_2/dependencies +++ b/Alpha_shapes_2/package_info/Alpha_shapes_2/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Alpha_shapes_2 Arithmetic_kernel +CGAL_Core Cartesian_kernel Hash_map Homogeneous_kernel diff --git a/Alpha_shapes_3/package_info/Alpha_shapes_3/dependencies b/Alpha_shapes_3/package_info/Alpha_shapes_3/dependencies index f0dc76c90d99..516a70a2bdeb 100644 --- a/Alpha_shapes_3/package_info/Alpha_shapes_3/dependencies +++ b/Alpha_shapes_3/package_info/Alpha_shapes_3/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Alpha_shapes_3 Arithmetic_kernel +CGAL_Core Cartesian_kernel Circulator Filtered_kernel diff --git a/Alpha_wrap_3/package_info/Alpha_wrap_3/dependencies b/Alpha_wrap_3/package_info/Alpha_wrap_3/dependencies index 7645e1ba53c5..a3f60578532c 100644 --- a/Alpha_wrap_3/package_info/Alpha_wrap_3/dependencies +++ b/Alpha_wrap_3/package_info/Alpha_wrap_3/dependencies @@ -4,6 +4,7 @@ Alpha_wrap_3 Arithmetic_kernel BGL Box_intersection_d +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Arithmetic_kernel/include/CGAL/BOOST_MP_arithmetic_kernel.h b/Arithmetic_kernel/include/CGAL/BOOST_MP_arithmetic_kernel.h index b1c1b1532e83..1ac38a242340 100644 --- a/Arithmetic_kernel/include/CGAL/BOOST_MP_arithmetic_kernel.h +++ b/Arithmetic_kernel/include/CGAL/BOOST_MP_arithmetic_kernel.h @@ -19,6 +19,10 @@ #ifdef CGAL_USE_BOOST_MP +#ifdef CGAL_USE_CORE +#include +#endif + //Currently already included in boost_mp.h //#include //#ifdef CGAL_USE_GMP @@ -26,20 +30,29 @@ //#endif // FIXME: the could be several kernels based on Boost.Multiprecision. - namespace CGAL { /** \ingroup CGAL_Arithmetic_kernel * \brief The Boost.Multiprecision set of exact number types */ + +#if !defined(CGAL_USE_CORE) || defined(CGAL_CORE_USE_GMP_BACKEND) struct BOOST_cpp_arithmetic_kernel : internal::Arithmetic_kernel_base { typedef boost::multiprecision::cpp_int Integer; typedef boost::multiprecision::cpp_rational Rational; }; +#else +typedef CORE_arithmetic_kernel BOOST_cpp_arithmetic_kernel; +#endif + #ifdef CGAL_USE_GMP +#if !defined(CGAL_USE_CORE) || !defined(CGAL_CORE_USE_GMP_BACKEND) struct BOOST_gmp_arithmetic_kernel : internal::Arithmetic_kernel_base { typedef boost::multiprecision::mpz_int Integer; typedef boost::multiprecision::mpq_rational Rational; }; +#else +typedef CORE_arithmetic_kernel BOOST_gmp_arithmetic_kernel; +#endif #endif template diff --git a/Arithmetic_kernel/include/CGAL/CORE_arithmetic_kernel.h b/Arithmetic_kernel/include/CGAL/CORE_arithmetic_kernel.h index c619f418de08..67586065fa5f 100644 --- a/Arithmetic_kernel/include/CGAL/CORE_arithmetic_kernel.h +++ b/Arithmetic_kernel/include/CGAL/CORE_arithmetic_kernel.h @@ -55,14 +55,6 @@ class CORE_arithmetic_kernel : public internal::Arithmetic_kernel_base { }; -template <> -struct Get_arithmetic_kernel{ - typedef CORE_arithmetic_kernel Arithmetic_kernel; -}; -template <> -struct Get_arithmetic_kernel{ - typedef CORE_arithmetic_kernel Arithmetic_kernel; -}; template <> struct Get_arithmetic_kernel{ typedef CORE_arithmetic_kernel Arithmetic_kernel; @@ -74,6 +66,8 @@ struct Get_arithmetic_kernel{ } //namespace CGAL +#include + #endif // CGAL_USE_CORE #endif // CGAL_CORE_ARITHMETIC_KERNEL_H diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Utils/Utils.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Utils/Utils.cpp index df21f6699ab9..b6bd521f6224 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Utils/Utils.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/Utils/Utils.cpp @@ -202,7 +202,7 @@ operator()(const Point_2& p, const X_monotone_curve_2& curve) const { auto points = painterOstream.getPointsList(curve); QPoint p_viewport = - view->mapFromScene(QPointF{p.x().doubleValue(), p.y().doubleValue()}); + view->mapFromScene(QPointF{CGAL::to_double(p.x()), CGAL::to_double(p.y())}); double min_dist = (std::numeric_limits::max)(); for (auto& vec : points) { diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_conic_traits_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_conic_traits_2.h index a850f5ef3c88..fd0215a1a1e4 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_conic_traits_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_conic_traits_2.h @@ -3316,9 +3316,9 @@ class Arr_conic_traits_2 { // sqrt((r - s)^2 + t^2) // const int or_fact = (cv.orientation() == CLOCKWISE) ? -1 : 1; - const Algebraic r = m_nt_traits->convert(or_fact * cv.r()); - const Algebraic s = m_nt_traits->convert(or_fact * cv.s()); - const Algebraic t = m_nt_traits->convert(or_fact * cv.t()); + const Algebraic r = m_nt_traits->convert(Integer(or_fact * cv.r())); + const Algebraic s = m_nt_traits->convert(Integer(or_fact * cv.s())); + const Algebraic t = m_nt_traits->convert(Integer(or_fact * cv.t())); const Algebraic cos_2phi = (r - s) / m_nt_traits->sqrt((r-s)*(r-s) + t*t); const Algebraic zero = 0; const Algebraic one = 1; @@ -3363,8 +3363,8 @@ class Arr_conic_traits_2 { // 4*r*s - t^2 4*r*s - t^2 // // The denominator (4*r*s - t^2) must be negative for hyperbolas. - const Algebraic u = m_nt_traits->convert(or_fact * cv.u()); - const Algebraic v = m_nt_traits->convert(or_fact * cv.v()); + const Algebraic u = m_nt_traits->convert(Integer(or_fact * cv.u())); + const Algebraic v = m_nt_traits->convert(Integer(or_fact * cv.v())); const Algebraic det = 4*r*s - t*t; Algebraic x0, y0; @@ -3803,9 +3803,9 @@ class Arr_conic_traits_2 { auto u = cv.u(); auto v = cv.v(); auto w = cv.w(); - Algebraic* xs_end = m_nt_traits->solve_quadratic_equation(t*t - four*r*s, - two*t*v - four*s*u, - v*v - four*s*w, + Algebraic* xs_end = m_nt_traits->solve_quadratic_equation(Integer(t*t - four*r*s), + Integer(two*t*v - four*s*u), + Integer(v*v - four*s*w), xs); auto n_xs = static_cast(xs_end - xs); @@ -3816,15 +3816,15 @@ class Arr_conic_traits_2 { if (CGAL::sign(cv.t()) == ZERO) { // The two vertical tangency points have the same y coordinate: - ys[0] = m_nt_traits->convert(-v) / m_nt_traits->convert(two*s); + ys[0] = m_nt_traits->convert(Integer(- v)) / m_nt_traits->convert(Integer(two * s)); n_ys = 1; } else { - ys_end = m_nt_traits->solve_quadratic_equation(four*r*s*s - s*t*t, - four*r*s*v - two*s*t*u, - r*v*v - t*u*v + - t*t*w, + ys_end = m_nt_traits->solve_quadratic_equation(Integer(four*r*s*s - s*t*t), + Integer(four*r*s*v - two*s*t*u), + Integer((r*v*v - t*u*v) + (t*t*w)), ys); + n_ys = static_cast(ys_end - ys); } @@ -3837,7 +3837,7 @@ class Arr_conic_traits_2 { } else { for (int j = 0; j < n_ys; ++j) { - if (CGAL::compare(m_nt_traits->convert(two*s) * ys[j], + if (CGAL::compare(m_nt_traits->convert(Integer(two*s)) * ys[j], -(m_nt_traits->convert(t) * xs[i] + m_nt_traits->convert(v))) == EQUAL) { @@ -3904,10 +3904,11 @@ class Arr_conic_traits_2 { auto u = cv.u(); auto v = cv.v(); auto w = cv.w(); - Algebraic* ys_end = m_nt_traits->solve_quadratic_equation(t*t - four*r*s, - two*t*u - four*r*v, - u*u - four*r*w, - ys); + Algebraic* ys_end = m_nt_traits->template + solve_quadratic_equation(t*t - four*r*s, + two*t*u - four*r*v, + u*u - four*r*w, + ys); auto n = static_cast(ys_end - ys); // Compute the x coordinates and construct the horizontal tangency points. @@ -3915,7 +3916,7 @@ class Arr_conic_traits_2 { // Having computed y, x is the single solution to the quadratic equation // above, and since its discriminant is 0, x is simply given by: Algebraic x = -(m_nt_traits->convert(t)*ys[i] + m_nt_traits->convert(u)) / - m_nt_traits->convert(two*r); + m_nt_traits->convert(Integer(two*r)); ps[i] = Point_2(x, ys[i]); } diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_geometry_traits/Circle_segment_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_geometry_traits/Circle_segment_2.h index f46489ba9690..dfa75584c53f 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_geometry_traits/Circle_segment_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_geometry_traits/Circle_segment_2.h @@ -1430,8 +1430,8 @@ class _X_monotone_circle_segment_2 { { // Actually compare the slopes. const bool swap_res = (sign_denom1 != sign_denom2); - const CoordNT A = (cv.y0() - y0())*p.x() + (y0()*cv.x0() - cv.y0()*x0()); - const CoordNT B = (cv.x0() - x0())*p.y(); + const CoordNT A = NT(cv.y0() - y0())*p.x() + (y0()*cv.x0() - cv.y0()*x0()); + const CoordNT B = NT(cv.x0() - x0())*p.y(); slope_res = CGAL::compare (A, B); diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_geometry_traits/Conic_arc_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_geometry_traits/Conic_arc_2.h index db6c0fccfc83..08126475b5a0 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_geometry_traits/Conic_arc_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_geometry_traits/Conic_arc_2.h @@ -1110,9 +1110,9 @@ class Conic_arc_2 { // Nt_traits nt_traits; const int or_fact = (m_orient == CLOCKWISE) ? -1 : 1; - const Algebraic r = nt_traits.convert(or_fact * m_r); - const Algebraic s = nt_traits.convert(or_fact * m_s); - const Algebraic t = nt_traits.convert(or_fact * m_t); + const Algebraic r = nt_traits.convert(Integer(or_fact * m_r)); + const Algebraic s = nt_traits.convert(Integer(or_fact * m_s)); + const Algebraic t = nt_traits.convert(Integer(or_fact * m_t)); const Algebraic cos_2phi = (r - s) / nt_traits.sqrt((r-s)*(r-s) + t*t); const Algebraic zero = 0; const Algebraic one = 1; @@ -1158,8 +1158,8 @@ class Conic_arc_2 { // 4*r*s - t^2 4*r*s - t^2 // // The denominator (4*r*s - t^2) must be negative for hyperbolas. - const Algebraic u = nt_traits.convert(or_fact * m_u); - const Algebraic v = nt_traits.convert(or_fact * m_v); + const Algebraic u = nt_traits.convert(Integer(or_fact * m_u)); + const Algebraic v = nt_traits.convert(Integer(or_fact * m_v)); const Algebraic det = 4*r*s - t*t; Algebraic x0, y0; diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_geometry_traits/Conic_intersections_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_geometry_traits/Conic_intersections_2.h index 223fcda24e9f..3af830c193da 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_geometry_traits/Conic_intersections_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_geometry_traits/Conic_intersections_2.h @@ -64,8 +64,9 @@ int compute_resultant_roots(const Nt_traits& nt_traits, } // Act according to the degree of the first conic curve. - const typename Nt_traits::Integer two = 2; - typename Nt_traits::Integer c[5]; + typedef typename Nt_traits::Integer Integer; + const Integer two = 2; + Integer c[5]; unsigned int degree = 4; typename Nt_traits::Algebraic* xs_end; @@ -73,7 +74,7 @@ int compute_resultant_roots(const Nt_traits& nt_traits, // The first curve has no quadratic coefficients, and represents a line. if (CGAL::sign (v1) == ZERO) { // The first line is u1*x + w1 = 0, therefore: - xs[0] = nt_traits.convert(-w1) / nt_traits.convert(u1); + xs[0] = nt_traits.convert(Integer(- w1)) / nt_traits.convert(u1); return 1; } @@ -87,7 +88,7 @@ int compute_resultant_roots(const Nt_traits& nt_traits, // Return if the two lines are parallel if (CGAL::sign (c[1]) == ZERO) return 0; - xs[0] = nt_traits.convert(-c[0]) / nt_traits.convert(c[1]); + xs[0] = nt_traits.convert(Integer(- c[0])) / nt_traits.convert(c[1]); return 1; } diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_rat_arc/Algebraic_point_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_rat_arc/Algebraic_point_2.h index 460bbe432a7a..c5b38c13a8c6 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_rat_arc/Algebraic_point_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_rat_arc/Algebraic_point_2.h @@ -225,10 +225,11 @@ class Algebraic_point_2_rep : public Base_rational_arc_ds_1 if (CGAL::compare( CGAL::width(y_bfi), CGAL::lower(CGAL::abs(y_bfi)) * eps) - == SMALLER) + == SMALLER){ return std::make_pair( Bound(CGAL::lower(y_bfi)), Bound(CGAL::upper(y_bfi))); + } } else precision*=2; } @@ -287,10 +288,11 @@ class Algebraic_point_2_rep : public Base_rational_arc_ds_1 if (CGAL::zero_in(y_denom_bfi) == false) { BFI y_bfi(y_numer_bfi/y_denom_bfi); - if (CGAL::width(y_bfi) < eps ) + if (CGAL::width(y_bfi) < eps ){ return std::make_pair( Bound(CGAL::lower(y_bfi)), Bound(CGAL::upper(y_bfi))); + } } else precision*=2; diff --git a/Arrangement_on_surface_2/include/CGAL/CORE_algebraic_number_traits.h b/Arrangement_on_surface_2/include/CGAL/CORE_algebraic_number_traits.h index c3fd592a7d66..c3e941fdab8e 100644 --- a/Arrangement_on_surface_2/include/CGAL/CORE_algebraic_number_traits.h +++ b/Arrangement_on_surface_2/include/CGAL/CORE_algebraic_number_traits.h @@ -106,7 +106,7 @@ class CORE_algebraic_number_traits ix1 = scaled_x1.BigIntValue(); ix2 = scaled_x2.BigIntValue(); - if (CORE::abs (ix2 - ix1) > one) + if (CGAL::abs (ix2 - ix1) > one) break; // Scale the values by a factor of 2. @@ -179,9 +179,9 @@ class CORE_algebraic_number_traits temp_gcd = numer_gcd; denom_lcm *= denom; - denom_lcm /= CORE::gcd (temp_lcm, denom); + denom_lcm /= CGAL::gcd (temp_lcm, denom); - numer_gcd = CORE::gcd (temp_gcd, numer); + numer_gcd = CGAL::gcd (temp_gcd, numer); } ++q_iter; @@ -246,8 +246,8 @@ class CORE_algebraic_number_traits if (sign_disc == ZERO) { - // We have one real root with mutliplicity 2. - *oi = -Algebraic (b) / Algebraic (2*a); + // We have one real root with multiplicity 2. + *oi = -Algebraic (b) / Algebraic (NT(2*a)); ++oi; } else if (sign_disc == POSITIVE) @@ -255,7 +255,7 @@ class CORE_algebraic_number_traits // We have two distinct real roots. We return them in ascending order. const Algebraic sqrt_disc = CGAL::sqrt (Algebraic (disc)); const Algebraic alg_b = b; - const Algebraic alg_2a = 2*a; + const Algebraic alg_2a = NT(2*a); if (sign_a == POSITIVE) { @@ -334,7 +334,7 @@ class CORE_algebraic_number_traits temp_lcm = denom_lcm; denom_lcm *= denom; - denom_lcm /= CORE::gcd (temp_lcm, denom); + denom_lcm /= CGAL::gcd (temp_lcm, denom); } index--; diff --git a/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/gfx/Curve_renderer_2.h b/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/gfx/Curve_renderer_2.h index fcf022620d90..f940e49b91b8 100644 --- a/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/gfx/Curve_renderer_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/gfx/Curve_renderer_2.h @@ -865,7 +865,7 @@ void draw(const Arc_2& arc, get_pixel_coords(l, y_clip, pix_beg); get_pixel_coords(ptmp->left, it->second ? engine.y_max_r : engine.y_min_r, pix_end); - if(CGAL_ABS(ptmp->left - l) <= engine.pixel_w_r*2) { + if(CGAL_ABS(Rational(ptmp->left - l)) <= engine.pixel_w_r*2) { Coordinate_2 xy(Coordinate_1(pt), *support, arc.arcno()); Rational _; diff --git a/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/gfx/Curve_renderer_internals.h b/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/gfx/Curve_renderer_internals.h index 636b7919b334..a8a739cc40f4 100644 --- a/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/gfx/Curve_renderer_internals.h +++ b/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/gfx/Curve_renderer_internals.h @@ -695,7 +695,7 @@ bool get_range_QF_1(int var, const NT& l_, const NT& r_, const NT& key, while(der_it != der_begin) { --der_it; - e1 = xsum_abs * e1 + CGAL_ABS(x1 * z1); + e1 = xsum_abs * e1 + CGAL_ABS(NT(x1 * z1)); z1 = x0*z1 + x1*y1; y1 = y1*x0 + x1*y0; y0 = x0*y0 + extract(*cache_it)*(*der_it); @@ -726,7 +726,7 @@ bool get_range_QF_1(int var, const NT& l_, const NT& r_, const NT& key, NT y0 = extract(*cache_it), y1(0), z1(0), e1(0); while(cache_it != begin) { --cache_it; - e1 = xsum_abs * e1 + CGAL_ABS(x1*z1); + e1 = xsum_abs * e1 + CGAL_ABS(NT(x1*z1)); z1 = x0*z1 + x1*y1; y1 = y1*x0 + x1*y0; y0 = x0*y0 + extract(*cache_it); diff --git a/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/gfx/Curve_renderer_traits.h b/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/gfx/Curve_renderer_traits.h index 5300354df86a..7520f9cfad29 100644 --- a/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/gfx/Curve_renderer_traits.h +++ b/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/gfx/Curve_renderer_traits.h @@ -336,7 +336,7 @@ struct Curve_renderer_traits, CORE::BigRat > : //! Specialization for \c CORE::BigFloat template <> -struct Curve_renderer_traits +struct Curve_renderer_traits : public Curve_renderer_traits_base { @@ -347,7 +347,7 @@ struct Curve_renderer_traits typedef Integer result_type; Integer operator()(const Rational& x) const { - return x.BigIntValue(); + return numerator(x)/denominator(x); } }; @@ -400,7 +400,7 @@ struct Curve_renderer_traits : typedef Integer result_type; Integer operator()(const Rational& x) const { - return x.BigIntValue(); + return numerator(x)/denominator(x); } }; @@ -409,9 +409,7 @@ struct Curve_renderer_traits : typedef std::size_t result_type; inline result_type operator()(const Float& key) const { - const CORE::BigRatRep& rep = key.getRep(); - std::size_t ret = reinterpret_cast(&rep); - return ret; + return std::hash()(key); } }; }; diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test.cmake b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test.cmake index 59f174e0ba60..bc8f8c10c5cb 100644 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test.cmake +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test.cmake @@ -877,7 +877,7 @@ endfunction() #---------------------------------------------------------------------# function(test_polycurve_conic_traits) # echo polycurve test starting - if(CGAL_DISABLE_GMP) + if(NOT CGAL_Core_FOUND) MESSAGE(STATUS "test_polycurve_conic_traits requires CORE and will not be executed") return() endif() @@ -948,7 +948,7 @@ endfunction() # polycurve bezier traits #---------------------------------------------------------------------# function(test_polycurve_bezier_traits) - if(CGAL_DISABLE_GMP) + if(NOT CGAL_Core_FOUND) MESSAGE(STATUS "test_polycurve_bezier_traits requires CORE and will not be executed") return() endif() @@ -1057,7 +1057,7 @@ endfunction() # conic traits #---------------------------------------------------------------------# function(test_conic_traits) - if(CGAL_DISABLE_GMP) + if(NOT CGAL_Core_FOUND) MESSAGE(STATUS "test_conic_traits requires CORE and will not be executed") return() endif() @@ -1188,7 +1188,7 @@ endfunction() # bezier traits #---------------------------------------------------------------------# function(test_bezier_traits) - if(CGAL_DISABLE_GMP) + if(NOT CGAL_Core_FOUND) MESSAGE(STATUS "test_bezier_traits requires CORE and will not be executed") return() endif() @@ -1235,7 +1235,7 @@ endfunction() # rational arc traits #---------------------------------------------------------------------# function(test_rational_arc_traits) - if(CGAL_DISABLE_GMP) + if(NOT CGAL_Core_FOUND) MESSAGE(STATUS "test_rational_arc_traits requires CORE and will not be executed") return() endif() @@ -1302,7 +1302,7 @@ endfunction() #---------------------------------------------------------------------# function(test_algebraic_traits_core) #TODO: Adapt - if(CGAL_DISABLE_GMP) + if(NOT CGAL_Core_FOUND) MESSAGE(STATUS "test_algebraic_traits_core requires CORE and will not be executed") return() endif() diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/data/polycurves_bezier/points b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/data/polycurves_bezier/points index b81a26dacc18..0382a34de18c 100644 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/data/polycurves_bezier/points +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/data/polycurves_bezier/points @@ -7,18 +7,18 @@ # We need the bezier curve (not polycurve) to contruct a bezier point. # # Point ID: 0 -r c 4 0 0 500 200 100 200 900 0 0.5 +r c 4 0 0 500 200 100 200 900 0 1/2 # Point ID: 1 -r c 4 900 0 1200 600 1500 400 900 600 0.3 +r c 4 900 0 1200 600 1500 400 900 600 3/10 # Point id: 2 -r c 4 0 0 100 200 500 200 900 0 0.0 +r c 4 0 0 100 200 500 200 900 0 0 # Point id: 3 -r c 4 900 0 1200 300 1500 400 2000 450 1.0 +r c 4 900 0 1200 300 1500 400 2000 450 1 # Point id: 4 -r c 4 2000 450 2100 300 2200 200 2300 450 0.0 +r c 4 2000 450 2100 300 2200 200 2300 450 0 # Point id: 5 -r c 4 2300 450 2500 500 2800 600 3000 450 1.0 +r c 4 2300 450 2500 500 2800 600 3000 450 1 # Point id: 6 -r c 4 0 0 100 200 500 200 900 0 0.0 +r c 4 0 0 100 200 500 200 900 0 0 # Point id: 7 -r c 4 2300 450 2500 500 2800 600 3000 450 1.0 \ No newline at end of file +r c 4 2300 450 2500 500 2800 600 3000 450 1 \ No newline at end of file diff --git a/Barycentric_coordinates_2/package_info/Barycentric_coordinates_2/dependencies b/Barycentric_coordinates_2/package_info/Barycentric_coordinates_2/dependencies index ee1e1d6538ae..1ea1e70b883e 100644 --- a/Barycentric_coordinates_2/package_info/Barycentric_coordinates_2/dependencies +++ b/Barycentric_coordinates_2/package_info/Barycentric_coordinates_2/dependencies @@ -2,6 +2,7 @@ Algebraic_foundations Arithmetic_kernel BGL Barycentric_coordinates_2 +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Boolean_set_operations_2/package_info/Boolean_set_operations_2/dependencies b/Boolean_set_operations_2/package_info/Boolean_set_operations_2/dependencies index a4d2b53c7b30..c5720a8c2b1f 100644 --- a/Boolean_set_operations_2/package_info/Boolean_set_operations_2/dependencies +++ b/Boolean_set_operations_2/package_info/Boolean_set_operations_2/dependencies @@ -2,6 +2,7 @@ Algebraic_foundations Arithmetic_kernel Arrangement_on_surface_2 Boolean_set_operations_2 +CGAL_Core Cartesian_kernel Circular_kernel_2 Circulator diff --git a/CGAL_Core/include/CGAL/CORE/BigFloat.h b/CGAL_Core/include/CGAL/CORE/BigFloat.h index 6c7a8abff4ca..de9ed2f55089 100644 --- a/CGAL_Core/include/CGAL/CORE/BigFloat.h +++ b/CGAL_Core/include/CGAL/CORE/BigFloat.h @@ -59,7 +59,7 @@ class CGAL_CORE_EXPORT BigFloat : public RCBigFloat { /// constructor for const char* (default base = 10) BigFloat(const char* s) : RCBigFloat(new BigFloatRep(s)) {} /// constructor for std::string(default base = 10) - BigFloat(const std::string& s) : RCBigFloat(new BigFloatRep(s)) {} + BigFloat(const std::string& s) : RCBigFloat(new BigFloatRep(s.c_str())) {} /// constructor for int and long // This is a hack because in Sturm, we need to approximate any @@ -106,6 +106,9 @@ class CGAL_CORE_EXPORT BigFloat : public RCBigFloat { explicit BigFloat(BigFloatRep* r, bool) : RCBigFloat(r) { } + operator BigRat() const { + return this->BigRatValue(); + } //@} @@ -510,32 +513,6 @@ inline long minStar(long m, long n) { } /// \name Functions for Compatibility with BigInt (needed by Poly, Curves) //@{ -/// isDivisible(a,b) = "is a divisible by b" -/** Assuming that a and b are in coanonized forms. - Defined to be true if mantissa(b) | mantissa(a) && - exp(b) = min*(exp(b), exp(a)). - * This concepts assume a and b are exact BigFloats. - */ -inline bool isDivisible(const BigFloat& a, const BigFloat& b) { - // assert: a and b are exact BigFloats. - if (sign(a.m()) == 0) return true; - if (sign(b.m()) == 0) return false; - unsigned long bin_a = getBinExpo(a.m()); - unsigned long bin_b = getBinExpo(b.m()); - - BigInt m_a = a.m() >> bin_a; - BigInt m_b = b.m() >> bin_b; - long e_a = bin_a + BigFloatRep::bits(a.exp()); - long e_b = bin_b + BigFloatRep::bits(b.exp()); - long dx = minStar(e_a, e_b); - - return isDivisible(m_a, m_b) && (dx == e_b); -} - -inline bool isDivisible(double x, double y) { - //Are these exact? - return isDivisible(BigFloat(x), BigFloat(y)); -} /// div_exact(x,y) returns the BigFloat quotient of x divided by y /** This is defined only if isDivisible(x,y). @@ -548,7 +525,6 @@ inline bool isDivisible(double x, double y) { // normalizing it then we get zero. inline BigFloat div_exact(const BigFloat& x, const BigFloat& y) { BigInt z; - CGAL_assertion (isDivisible(x,y)); unsigned long bin_x = getBinExpo(x.m()); unsigned long bin_y = getBinExpo(y.m()); @@ -615,15 +591,20 @@ inline BigFloat gcd(const BigFloat& a, const BigFloat& b) { //}// -// constructor BigRat from BigFloat -inline BigRat::BigRat(const BigFloat& f) : RCBigRat(new BigRatRep()){ - *this = f.BigRatValue(); +inline double doubleValue(const BigFloat& bf) +{ + return bf.doubleValue(); } + +inline long longValue(const BigFloat& bf) +{ + return bf.longValue(); +} + } //namespace CORE #ifdef CGAL_HEADER_ONLY #include -#include #endif // CGAL_HEADER_ONLY #include diff --git a/CGAL_Core/include/CGAL/CORE/BigFloatRep.h b/CGAL_Core/include/CGAL/CORE/BigFloatRep.h index 4cb5f461b058..cce0771f06fa 100644 --- a/CGAL_Core/include/CGAL/CORE/BigFloatRep.h +++ b/CGAL_Core/include/CGAL/CORE/BigFloatRep.h @@ -317,7 +317,7 @@ inline void BigFloatRep::eliminateTrailingZeroes() { // builtin functions inline extLong BigFloatRep::lMSB() const { if (!isZeroIn()) - return extLong(floorLg(abs(m) - err)) + bits(exp); + return extLong(floorLg(BigInt(abs(m) - err))) + bits(exp); else return extLong(CORE_negInfty); } @@ -327,7 +327,7 @@ inline extLong BigFloatRep::lMSB() const { * Not well-defined if zero is in the interval. */ inline extLong BigFloatRep::uMSB() const { - return extLong(floorLg(abs(m) + err)) + bits(exp); + return extLong(floorLg(BigInt(abs(m) + err))) + bits(exp); } inline extLong BigFloatRep::MSB() const { diff --git a/CGAL_Core/include/CGAL/CORE/BigFloat_impl.h b/CGAL_Core/include/CGAL/CORE/BigFloat_impl.h index 59723f30df83..2fabfd36124f 100644 --- a/CGAL_Core/include/CGAL/CORE/BigFloat_impl.h +++ b/CGAL_Core/include/CGAL/CORE/BigFloat_impl.h @@ -194,8 +194,7 @@ void BigFloatRep :: truncM(const BigFloatRep& B, const extLong& r, const extLong err = 2; exp = B.exp + t; } else // t < chunkCeil(clLg(B.err)) - core_error(std::string("BigFloat error: truncM called with stricter") - + "precision than current error.", __FILE__, __LINE__, true); + CGAL_error_msg("BigFloat error: truncM called with stricter precision than current error."); } else {// B.m == 0 long t = chunkFloor(- a.asLong()) - B.exp; @@ -204,8 +203,7 @@ void BigFloatRep :: truncM(const BigFloatRep& B, const extLong& r, const extLong err = 1; exp = B.exp + t; } else // t < chunkCeil(clLg(B.err)) - core_error(std::string("BigFloat error: truncM called with stricter") - + "precision than current error.", __FILE__, __LINE__, true); + CGAL_error_msg("BigFloat error: truncM called with stricter precision than current error."); } } @@ -216,7 +214,7 @@ CGAL_INLINE_FUNCTION void BigFloatRep::approx(const BigFloatRep& B, const extLong& r, const extLong& a) { if (B.err) { - if (1 + clLg(B.err) <= bitLength(B.m)) + if (static_cast(1 + clLg(B.err)) <= bitLength(B.m)) truncM(B, r + 1, a); else // 1 + clLg(B.err) > lg(B.m) truncM(B, CORE_posInfty, a); @@ -258,7 +256,7 @@ void BigFloatRep::div(const BigInt& N, const BigInt& D, exp = 0; } } else // D == 0 - core_error( "BigFloat error: zero divisor.", __FILE__, __LINE__, true); + CGAL_error_msg( "BigFloat error: zero divisor."); // Call normalization globally -- IP 10/9/98 normal(); @@ -455,6 +453,7 @@ void BigFloatRep::centerize(const BigFloatRep& a, const BigFloatRep& b) { // Zilin & Vikram, 08/24/04 // err = 1 + longValue(chunkShift(r.m, r.exp - exp)); BigInt E = chunkShift(r.m, r.exp - exp); + E = abs(E); bigNormal(E); } @@ -538,8 +537,7 @@ void BigFloatRep :: div(const BigFloatRep& x, const BigFloatRep& y, bigNormal(bigErr); } } else {// y.m <= y.err - core_error("BigFloat error: possible zero divisor.", - __FILE__, __LINE__, true); + CGAL_error_msg("BigFloat error: possible zero divisor."); } // Call normalization globally -- IP 10/9/98 @@ -734,8 +732,7 @@ void BigFloatRep::sqrt(const BigFloatRep& x, const extLong& a, const BigFloat& A } // end of case with error in mantissa }//else } else - core_error("BigFloat error: squareroot called with negative operand.", - __FILE__, __LINE__, true); + CGAL_error_msg("BigFloat error: squareroot called with negative operand."); } //sqrt with initial approximation // compareMExp(x) @@ -822,8 +819,7 @@ BigFloatRep::toDecimal(unsigned int width, bool Scientific) const { if (err > 0 && err >= abs(m)) { // if err is larger than mantissa, sign and significant values // can not be determined. - core_error("BigFloat error: Error is too big!", - __FILE__, __LINE__, false); + CGAL_CORE_warning_msg(true, "BigFloat error: Error is too big!"); decOut.rep = "0.0e0"; // error is too big decOut.isScientific = false; decOut.noSignificant = 0; @@ -869,7 +865,7 @@ BigFloatRep::toDecimal(unsigned int width, bool Scientific) const { M <<= e2; // M = x * 2^(e2) } - std::string decRep = M.get_str(); + std::string decRep = M.convert_to(); // Determine the "significant part" of this string, i.e. the part which // is guaranteed to be correct in the presence of error, // except that the last digit which might be subject to +/- 1. @@ -1003,8 +999,7 @@ void BigFloatRep :: fromString(const char *str, extLong prec ) { // NOTE: prec defaults to get_static_defBigFloatInputDigits() (see BigFloat.h) // check that prec is not INFTY if (prec.isInfty()) - core_error("BigFloat error: infinite precision not allowed", - __FILE__, __LINE__, true); + CGAL_error_msg("BigFloat error: infinite precision not allowed"); const char *e = strchr(str, 'e'); int dot = 0; diff --git a/CGAL_Core/include/CGAL/CORE/BigInt.h b/CGAL_Core/include/CGAL/CORE/BigInt.h index 6ab3aeb861b0..8904db58b6f4 100644 --- a/CGAL_Core/include/CGAL/CORE/BigInt.h +++ b/CGAL_Core/include/CGAL/CORE/BigInt.h @@ -24,448 +24,113 @@ #ifndef _CORE_BIGINT_H_ #define _CORE_BIGINT_H_ -#include +#include #include #include #include -namespace CORE { - -class BigIntRep : public RCRepImpl { -public: - BigIntRep() { - mpz_init(mp); - } - // Note : should the copy-ctor be allowed at all ? [Sylvain Pion] - BigIntRep(const BigIntRep& z) : RCRepImpl() { - mpz_init_set(mp, z.mp); - } - BigIntRep(signed char c) { - mpz_init_set_si(mp, c); - } - BigIntRep(unsigned char c) { - mpz_init_set_ui(mp, c); - } - BigIntRep(signed int i) { - mpz_init_set_si(mp, i); - } - BigIntRep(unsigned int i) { - mpz_init_set_ui(mp, i); - } - BigIntRep(signed short int s) { - mpz_init_set_si(mp, s); - } - BigIntRep(unsigned short int s) { - mpz_init_set_ui(mp, s); - } - BigIntRep(signed long int l) { - mpz_init_set_si(mp, l); - } - BigIntRep(unsigned long int l) { - mpz_init_set_ui(mp, l); - } - BigIntRep(float f) { - mpz_init_set_d(mp, f); - } - BigIntRep(double d) { - mpz_init_set_d(mp, d); - } - BigIntRep(const char* s, int base=0) { - mpz_init_set_str(mp, s, base); - } - BigIntRep(const std::string& s, int base=0) { - mpz_init_set_str(mp, s.c_str(), base); - } - explicit BigIntRep(mpz_srcptr z) { - mpz_init_set(mp, z); - } - ~BigIntRep() { - mpz_clear(mp); - } - - CGAL_CORE_EXPORT CORE_NEW(BigIntRep) - CGAL_CORE_EXPORT CORE_DELETE(BigIntRep) - - mpz_srcptr get_mp() const { - return mp; - } - mpz_ptr get_mp() { - return mp; - } -private: - mpz_t mp; -}; - -typedef RCImpl RCBigInt; -class CGAL_CORE_EXPORT BigInt : public RCBigInt { -public: - /// \name Constructors - //@{ - /// default constructor - BigInt() : RCBigInt(new BigIntRep()) {} - /// constructor for signed char - BigInt(signed char x) : RCBigInt(new BigIntRep(x)) {} - /// constructor for unsigned char - BigInt(unsigned char x) : RCBigInt(new BigIntRep(x)) {} - /// constructor for signed short int - BigInt(signed short int x) : RCBigInt(new BigIntRep(x)) {} - /// constructor for unsigned short int - BigInt(unsigned short int x) : RCBigInt(new BigIntRep(x)) {} - /// constructor for signed int - BigInt(signed int x) : RCBigInt(new BigIntRep(x)) {} - /// constructor for unsigned int - BigInt(unsigned int x) : RCBigInt(new BigIntRep(x)) {} - /// constructor for signed long int - BigInt(signed long int x) : RCBigInt(new BigIntRep(x)) {} - /// constructor for unsigned long int - BigInt(unsigned long int x) : RCBigInt(new BigIntRep(x)) {} - /// constructor for float - BigInt(float x) : RCBigInt(new BigIntRep(x)) {} - /// constructor for double - BigInt(double x) : RCBigInt(new BigIntRep(x)) {} - /// constructor for const char* with base - BigInt(const char* s, int base=0) : RCBigInt(new BigIntRep(s, base)) {} - /// constructor for std::string with base - BigInt(const std::string& s, int base=0) : RCBigInt(new BigIntRep(s, base)) {} - /// constructor for mpz_srcptr - explicit BigInt(mpz_srcptr z) : RCBigInt(new BigIntRep(z)) {} - //@} - - /// \name Copy-Assignment-Destructor - //@{ - /// copy constructor - BigInt(const BigInt& rhs) : RCBigInt(rhs) { - rep->incRef(); - } - /// assignment operator - BigInt& operator=(const BigInt& rhs) { - if (this != &rhs) { - rep->decRef(); - rep = rhs.rep; - rep->incRef(); - } - return *this; - } - /// destructor - ~BigInt() { - rep->decRef(); - } - //@} - - /// \name Overloaded operators - //@{ - BigInt& operator +=(const BigInt& rhs) { - makeCopy(); - mpz_add(get_mp(), get_mp(), rhs.get_mp()); - return *this; - } - BigInt& operator -=(const BigInt& rhs) { - makeCopy(); - mpz_sub(get_mp(), get_mp(), rhs.get_mp()); - return *this; - } - BigInt& operator *=(const BigInt& rhs) { - makeCopy(); - mpz_mul(get_mp(), get_mp(), rhs.get_mp()); - return *this; - } - BigInt& operator /=(const BigInt& rhs) { - makeCopy(); - mpz_tdiv_q(get_mp(), get_mp(), rhs.get_mp()); - return *this; - } - BigInt& operator %=(const BigInt& rhs) { - makeCopy(); - mpz_tdiv_r(get_mp(), get_mp(), rhs.get_mp()); - return *this; - } - BigInt& operator &=(const BigInt& rhs) { - makeCopy(); - mpz_and(get_mp(), get_mp(), rhs.get_mp()); - return *this; - } - BigInt& operator |=(const BigInt& rhs) { - makeCopy(); - mpz_ior(get_mp(), get_mp(), rhs.get_mp()); - return *this; - } - BigInt& operator ^=(const BigInt& rhs) { - makeCopy(); - mpz_xor(get_mp(), get_mp(), rhs.get_mp()); - return *this; - } - BigInt& operator <<=(unsigned long ul) { - makeCopy(); - mpz_mul_2exp(get_mp(), get_mp(), ul); - return *this; - } - BigInt& operator >>=(unsigned long ul) { - makeCopy(); - mpz_tdiv_q_2exp(get_mp(), get_mp(), ul); - return *this; - } - //@} +#if !(defined(CGAL_CORE_USE_BOOST_BACKEND) && BOOST_VERSION > 107900 && defined(CGAL_USE_BOOST_MP)) && !defined(CGAL_DISABLE_GMP) +#define CGAL_CORE_USE_GMP_BACKEND 1 +#endif - /// \name unary, increment, decrement operators - //@{ - BigInt operator+() const { - return BigInt(*this); - } - BigInt operator-() const { - BigInt r; - mpz_neg(r.get_mp(), get_mp()); - return r; - } - BigInt& operator++() { - makeCopy(); - mpz_add_ui(get_mp(), get_mp(), 1); - return *this; - } - BigInt& operator--() { - makeCopy(); - mpz_sub_ui(get_mp(), get_mp(), 1); - return *this; - } - BigInt operator++(int) { - BigInt r(*this); - ++(*this); - return r; - } - BigInt operator--(int) { - BigInt r(*this); - --(*this); - return r; - } - //@} +namespace CORE { - /// \name Helper Functions - //@{ - /// Has Exact Division - static bool hasExactDivision() { - return false; - } - /// get mpz pointer (const) - mpz_srcptr get_mp() const { - return rep->get_mp(); - } - /// get mpz pointer - mpz_ptr get_mp() { - return rep->get_mp(); - } - //@} - - /// \name String Conversion Functions - //@{ - /// set value from const char* - int set_str(const char* s, int base = 0) { - makeCopy(); - return mpz_set_str(get_mp(), s, base); - } - /// convert to std::string - std::string get_str(int base = 10) const { - int n = mpz_sizeinbase (get_mp(), base) + 2; - char *buffer = new char[n]; - mpz_get_str(buffer, base, get_mp()); - std::string result(buffer); - delete [] buffer; - return result; - } - //@} +#ifdef CGAL_CORE_USE_GMP_BACKEND + typedef boost::multiprecision::mpz_int BigInt; +#else + typedef boost::multiprecision::cpp_int BigInt; +#endif - /// \name Conversion Functions - //@{ - /// intValue - int intValue() const { - return static_cast(mpz_get_si(get_mp())); - } - /// longValue - long longValue() const { - return mpz_get_si(get_mp()); - } - /// ulongValue - unsigned long ulongValue() const { - return mpz_get_ui(get_mp()); - } - /// doubleValue - double doubleValue() const { - return mpz_get_d(get_mp()); - } - //@} -}; - -inline BigInt operator+(const BigInt& a, const BigInt& b) { - BigInt r; - mpz_add(r.get_mp(), a.get_mp(), b.get_mp()); - return r; -} -inline BigInt operator-(const BigInt& a, const BigInt& b) { - BigInt r; - mpz_sub(r.get_mp(), a.get_mp(), b.get_mp()); - return r; -} -inline BigInt operator*(const BigInt& a, const BigInt& b) { - BigInt r; - mpz_mul(r.get_mp(), a.get_mp(), b.get_mp()); - return r; -} -inline BigInt operator/(const BigInt& a, const BigInt& b) { - BigInt r; - mpz_tdiv_q(r.get_mp(), a.get_mp(), b.get_mp()); - return r; -} -inline BigInt operator%(const BigInt& a, const BigInt& b) { - BigInt r; - mpz_tdiv_r(r.get_mp(), a.get_mp(), b.get_mp()); - return r; -} -inline BigInt operator&(const BigInt& a, const BigInt& b) { - BigInt r; - mpz_and(r.get_mp(), a.get_mp(), b.get_mp()); - return r; -} -inline BigInt operator|(const BigInt& a, const BigInt& b) { - BigInt r; - mpz_ior(r.get_mp(), a.get_mp(), b.get_mp()); - return r; -} -inline BigInt operator^(const BigInt& a, const BigInt& b) { - BigInt r; - mpz_xor(r.get_mp(), a.get_mp(), b.get_mp()); - return r; -} -inline BigInt operator<<(const BigInt& a, unsigned long ul) { - BigInt r; - mpz_mul_2exp(r.get_mp(), a.get_mp(), ul); - return r; -} -inline BigInt operator>>(const BigInt& a, unsigned long ul) { - BigInt r; - mpz_tdiv_q_2exp(r.get_mp(), a.get_mp(), ul); - return r; -} inline int cmp(const BigInt& x, const BigInt& y) { - return mpz_cmp(x.get_mp(), y.get_mp()); -} -inline bool operator==(const BigInt& a, const BigInt& b) { - return cmp(a, b) == 0; -} -inline bool operator!=(const BigInt& a, const BigInt& b) { - return cmp(a, b) != 0; -} -inline bool operator>=(const BigInt& a, const BigInt& b) { - return cmp(a, b) >= 0; -} -inline bool operator>(const BigInt& a, const BigInt& b) { - return cmp(a, b) > 0; -} -inline bool operator<=(const BigInt& a, const BigInt& b) { - return cmp(a, b) <= 0; -} -inline bool operator<(const BigInt& a, const BigInt& b) { - return cmp(a, b) < 0; + return x.compare(y); } -inline std::ostream& operator<<(std::ostream& o, const BigInt& x) { - //return CORE::operator<<(o, x.get_mp()); - return CORE::io_write(o, x.get_mp()); -} -inline std::istream& operator>>(std::istream& i, BigInt& x) { - x.makeCopy(); - //return CORE::operator>>(i, x.get_mp()); - return CORE::io_read(i, x.get_mp()); -} -/// sign -inline int sign(const BigInt& a) { - return mpz_sgn(a.get_mp()); -} -/// abs -inline BigInt abs(const BigInt& a) { - BigInt r; - mpz_abs(r.get_mp(), a.get_mp()); - return r; -} -/// neg -inline BigInt neg(const BigInt& a) { - BigInt r; - mpz_neg(r.get_mp(), a.get_mp()); - return r; -} -/// negate -inline void negate(BigInt& a) { - a.makeCopy(); - mpz_neg(a.get_mp(), a.get_mp()); -} -/// cmpabs -inline int cmpabs(const BigInt& a, const BigInt& b) { - return mpz_cmpabs(a.get_mp(), b.get_mp()); -} +inline int set_str(BigInt& a, const char* s) { + a = BigInt(s); + return 0; // should be -1 if not correct in the base (we ignore) + } -/// \name Conversion Functions -//@{ -/// longValue + /// longValue inline long longValue(const BigInt& a) { - return a.longValue(); -} -/// ulongValue -inline unsigned long ulongValue(const BigInt& a) { - return a.ulongValue(); + return a.convert_to(); } -/// doubleValue + + /// doubleValue inline double doubleValue(const BigInt& a) { - return a.doubleValue(); + return a.convert_to(); } -//@} - -/// \name File I/O Functions -//@{ -/// read from file -void readFromFile(BigInt& z, std::istream& in, long maxLength = 0); -/// write to file -void writeToFile(const BigInt& z, std::ostream& in, int base=10, int charsPerLine=80); -//@} - -/// \name Misc Functions -//@{ -/// isEven + + /// isEven inline bool isEven(const BigInt& z) { - return mpz_even_p(z.get_mp()); + return bit_test(z,0) == 0; } /// isOdd inline bool isOdd(const BigInt& z) { - return mpz_odd_p(z.get_mp()); -} - -/// get exponent of power 2 -inline unsigned long getBinExpo(const BigInt& z) { - return mpz_scan1(z.get_mp(), 0); -} -/// get exponent of power k -inline void getKaryExpo(const BigInt& z, BigInt& m, int& e, unsigned long k) { - mpz_t f; - mpz_init_set_ui(f, k); - m.makeCopy(); - e = mpz_remove(m.get_mp(), z.get_mp(), f); - mpz_clear(f); + return bit_test(z,0) == 1; } -/// divisible(x,y) = "x | y" inline bool isDivisible(const BigInt& x, const BigInt& y) { - return mpz_divisible_p(x.get_mp(), y.get_mp()) != 0; + BigInt q, r; + divide_qr(x, y, q, r); + return r.is_zero(); } + inline bool isDivisible(int x, int y) { return x % y == 0; } + inline bool isDivisible(long x, long y) { return x % y == 0; + +} + /// get exponent of power 2 +inline std::size_t getBinExpo(const BigInt& z) { + if (z.is_zero()) { + return (std::numeric_limits::max)(); + } + return lsb(abs(z)); +} + + // bit length +inline std::size_t bitLength(const BigInt& a){ + if (a.is_zero()) { + return 0; + } + return msb(abs(a))+1; +} + +/// floorLg -- floor of log_2(a) +/** Convention: a=0, floorLg(a) returns -1. + * This makes sense for integer a. + */ +inline long floorLg(const BigInt& a) { + assert(std::size_t((std::numeric_limits::max)()) > bitLength(a)); + return (sign(a) == 0) ? (-1) : static_cast(bitLength(a)-1); +} + + +/// div_rem +inline void div_rem(BigInt& q, BigInt& r, const BigInt& a, const BigInt& b) { + divide_qr(a, b, q, r); } -/// exact div + + + /// ulongValue +inline unsigned long ulongValue(const BigInt& a) { + assert(a >= BigInt(0)); + return a.convert_to(); +} + + /// exact div inline void divexact(BigInt& z, const BigInt& x, const BigInt& y) { - z.makeCopy(); - mpz_divexact(z.get_mp(), x.get_mp(), y.get_mp()); + BigInt r; + divide_qr(x, y, z, r ); // was void mpz_divexact (mpz_t q, const mpz_t n, const mpz_t d) Is this faster? + assert(r.is_zero()); } + // Chee (1/12/2004) The definition of div_exact(x,y) next // ensure that in Polynomials works with both NT=BigInt and NT=int: inline BigInt div_exact(const BigInt& x, const BigInt& y) { @@ -473,50 +138,19 @@ inline BigInt div_exact(const BigInt& x, const BigInt& y) { divexact(z, x, y); // z is set to x/y; return z; } + inline int div_exact(int x, int y) { return x/y; // precondition: isDivisible(x,y) } + inline long div_exact(long x, long y) { return x/y; // precondition: isDivisible(x,y) } - -/// gcd -inline BigInt gcd(const BigInt& a, const BigInt& b) { - BigInt r; - mpz_gcd(r.get_mp(), a.get_mp(), b.get_mp()); - return r; -} -/// div_rem -inline void div_rem(BigInt& q, BigInt& r, const BigInt& a, const BigInt& b) { - q.makeCopy(); - r.makeCopy(); - mpz_tdiv_qr(q.get_mp(), r.get_mp(), a.get_mp(), b.get_mp()); -} -/// power -inline void power(BigInt& c, const BigInt& a, unsigned long ul) { - c.makeCopy(); - mpz_pow_ui(c.get_mp(), a.get_mp(), ul); +inline BigInt gcd(const BigInt& a, const BigInt& b){ + return boost::multiprecision::gcd(a,b); } -// pow -inline BigInt pow(const BigInt& a, unsigned long ui) { - BigInt r; - power(r, a, ui); - return r; -} - -// bit length -inline int bitLength(const BigInt& a) { - return mpz_sizeinbase(a.get_mp(), 2); -} -/// floorLg -- floor of log_2(a) -/** Convention: a=0, floorLg(a) returns -1. - * This makes sense for integer a. - */ -inline long floorLg(const BigInt& a) { - return (sign(a) == 0) ? (-1) : (bitLength(a)-1); -} /// ceilLg -- ceiling of log_2(a) where a=BigInt, int or long /** Convention: a=0, ceilLg(a) returns -1. * This makes sense for integer a. @@ -524,20 +158,45 @@ inline long floorLg(const BigInt& a) { inline long ceilLg(const BigInt& a) { if (sign(a) == 0) return -1; - unsigned long len = bitLength(a); - return (mpz_scan1(a.get_mp(), 0) == len-1) ? (len-1) : len; + assert(std::size_t((std::numeric_limits::max)()) > bitLength(a)); + std::size_t len = static_cast(bitLength(a)); + + return (lsb(abs(a)) == len - 1) ? (static_cast(len) - 1) : static_cast(len); } + inline long ceilLg(long a) { // need this for Polynomial return ceilLg(BigInt(a)); } + inline long ceilLg(int a) { // need this for Polynomial return ceilLg(BigInt(a)); } -//@} +/// negate +inline void negate(BigInt& a) { + a= - a; +} + +/// get exponent of power k +inline void getKaryExpo(const BigInt& z, BigInt& m, int& e, unsigned long uk) { + BigInt k(uk), q, r; + e = 0; + m = z; + for(;;) { + divide_qr(m, k, q, r); + if (!r.is_zero()) break; + m = q; + ++e; + } +} + +inline void power(BigInt& c, const BigInt& a, unsigned long ul) { + c = pow(a, ul); +} + +} // namespace CORE -} //namespace CORE #endif // _CORE_BIGINT_H_ diff --git a/CGAL_Core/include/CGAL/CORE/BigRat.h b/CGAL_Core/include/CGAL/CORE/BigRat.h index 2fbad7d30b1b..cc0c8d5ed174 100644 --- a/CGAL_Core/include/CGAL/CORE/BigRat.h +++ b/CGAL_Core/include/CGAL/CORE/BigRat.h @@ -28,354 +28,35 @@ #include namespace CORE { +#ifdef CGAL_CORE_USE_GMP_BACKEND + typedef boost::multiprecision::mpq_rational BigRat; +#else + typedef boost::multiprecision::cpp_rational BigRat; +#endif -class BigRatRep : public RCRepImpl { -public: - BigRatRep() { - mpq_init(mp); - } - // Note : should the copy-ctor be allowed at all ? [Sylvain Pion] - BigRatRep(const BigRatRep& z) : RCRepImpl() { - mpq_init(mp); - mpq_set(mp, z.mp); - } - BigRatRep(signed char c) { - mpq_init(mp); - mpq_set_si(mp, c, 1); - } - BigRatRep(unsigned char c) { - mpq_init(mp); - mpq_set_ui(mp, c, 1); - } - BigRatRep(signed int i) { - mpq_init(mp); - mpq_set_si(mp, i, 1); - } - BigRatRep(unsigned int i) { - mpq_init(mp); - mpq_set_ui(mp, i, 1); - } - BigRatRep(signed short int s) { - mpq_init(mp); - mpq_set_si(mp, s, 1); - } - BigRatRep(unsigned short int s) { - mpq_init(mp); - mpq_set_ui(mp, s, 1); - } - BigRatRep(signed long int l) { - mpq_init(mp); - mpq_set_si(mp, l, 1); - } - BigRatRep(unsigned long int l) { - mpq_init(mp); - mpq_set_ui(mp, l, 1); - } - BigRatRep(float f) { - mpq_init(mp); - mpq_set_d(mp, f); - } - BigRatRep(double d) { - mpq_init(mp); - mpq_set_d(mp, d); - } - BigRatRep(const char* s) { - mpq_init(mp); - mpq_set_str(mp, s, 0); - } - BigRatRep(const std::string& s) { - mpq_init(mp); - mpq_set_str(mp, s.c_str(), 0); - } - explicit BigRatRep(mpq_srcptr q) { - mpq_init(mp); - mpq_set(mp, q); - } - BigRatRep(mpz_srcptr z) { - mpq_init(mp); - mpq_set_z(mp, z); - } - BigRatRep(mpz_srcptr n, mpz_srcptr d) { - mpq_init(mp); - mpz_set(mpq_numref(mp), n); - mpz_set(mpq_denref(mp), d); - mpq_canonicalize(mp); - } - ~BigRatRep() { - mpq_clear(mp); - } - - CGAL_CORE_EXPORT CORE_NEW(BigRatRep) - CGAL_CORE_EXPORT CORE_DELETE(BigRatRep) - - mpq_srcptr get_mp() const { - return mp; - } - mpq_ptr get_mp() { - return mp; - } -private: - mpq_t mp; -}; //BigRatRep - -class BigFloat; - -typedef RCImpl RCBigRat; -class BigRat : public RCBigRat { -public: - /// \name Constructors - //@{ - /// default constructor - BigRat() : RCBigRat(new BigRatRep()) {} - /// constructor for signed char - BigRat(signed char x) : RCBigRat(new BigRatRep(x)) {} - /// constructor for unsigned char - BigRat(unsigned char x) : RCBigRat(new BigRatRep(x)) {} - /// constructor for signed short int - BigRat(signed short int x) : RCBigRat(new BigRatRep(x)) {} - /// constructor for unsigned short int - BigRat(unsigned short int x) : RCBigRat(new BigRatRep(x)) {} - /// constructor for signed int - BigRat(signed int x) : RCBigRat(new BigRatRep(x)) {} - /// constructor for unsigned int - BigRat(unsigned int x) : RCBigRat(new BigRatRep(x)) {} - /// constructor for signed long int - BigRat(signed long int x) : RCBigRat(new BigRatRep(x)) {} - /// constructor for unsigned long int - BigRat(unsigned long int x) : RCBigRat(new BigRatRep(x)) {} - /// constructor for float - BigRat(float x) : RCBigRat(new BigRatRep(x)) {} - /// constructor for double - BigRat(double x) : RCBigRat(new BigRatRep(x)) {} - /// constructor for const char* with base - BigRat(const char* s) : RCBigRat(new BigRatRep(s)) {} - /// constructor for std::string with base - BigRat(const std::string& s) : RCBigRat(new BigRatRep(s)) {} - /// constructor for mpq_srcptr - explicit BigRat(mpq_srcptr z) : RCBigRat(new BigRatRep(z)) {} - /// constructor for BigInt - BigRat(const BigInt& z) : RCBigRat(new BigRatRep(z.get_mp())) {} - /// constructor for two BigInts - BigRat(const BigInt& n, const BigInt& d) - : RCBigRat(new BigRatRep(n.get_mp(), d.get_mp())) {} - /// constructor for BigFloat - BigRat(const BigFloat&); - //@} - - /// \name Copy-Assignment-Destructor - //@{ - /// copy constructor - BigRat(const BigRat& rhs) : RCBigRat(rhs) { - rep->incRef(); - } - /// assignment operator - BigRat& operator=(const BigRat& rhs) { - if (this != &rhs) { - rep->decRef(); - rep = rhs.rep; - rep->incRef(); - } - return *this; - } - /// destructor - ~BigRat() { - rep->decRef(); - } - //@} - /// \name Overloaded operators - //@{ - BigRat& operator +=(const BigRat& rhs) { - makeCopy(); - mpq_add(get_mp(), get_mp(), rhs.get_mp()); - return *this; - } - BigRat& operator -=(const BigRat& rhs) { - makeCopy(); - mpq_sub(get_mp(), get_mp(), rhs.get_mp()); - return *this; - } - BigRat& operator *=(const BigRat& rhs) { - makeCopy(); - mpq_mul(get_mp(), get_mp(), rhs.get_mp()); - return *this; - } - BigRat& operator /=(const BigRat& rhs) { - makeCopy(); - mpq_div(get_mp(), get_mp(), rhs.get_mp()); - return *this; - } - BigRat& operator <<=(unsigned long ul) { - makeCopy(); - mpq_mul_2exp(get_mp(), get_mp(), ul); - return *this; + inline BigInt numerator(const BigRat& q) + { + return boost::multiprecision::numerator(q); } - BigRat& operator >>=(unsigned long ul) { - makeCopy(); - mpq_div_2exp(get_mp(), get_mp(), ul); - return *this; - } - //@} - - /// \name div2, unary, increment, decrement operators - //@{ - /// exact division by 2 (this method is provided for compatibility) - BigRat div2() const { - BigRat r; BigRat t(2); // probably not most efficient way - mpq_div(r.get_mp(), get_mp(), t.get_mp()); - return r; - } - BigRat operator+() const { - return BigRat(*this); - } - BigRat operator-() const { - BigRat r; - mpq_neg(r.get_mp(), get_mp()); - return r; - } - BigRat& operator++() { - makeCopy(); - mpz_add(get_num_mp(),get_num_mp(),get_den_mp()); - return *this; - } - BigRat& operator--() { - makeCopy(); - mpz_sub(get_num_mp(),get_num_mp(),get_den_mp()); - return *this; - } - BigRat operator++(int) { - BigRat r(*this); - ++(*this); - return r; - } - BigRat operator--(int) { - BigRat r(*this); - --(*this); - return r; - } - //@} - - /// \name Helper Functions - //@{ - /// Canonicalize - void canonicalize() { - makeCopy(); - mpq_canonicalize(get_mp()); - } - /// Has Exact Division - static bool hasExactDivision() { - return true; - } - - /// return mpz pointer of numerator (const) - mpz_srcptr get_num_mp() const { - return mpq_numref(get_mp()); - } - /// return mpz pointer of numerator - mpz_ptr get_num_mp() { - return mpq_numref(get_mp()); - } - /// return mpz pointer of denominator - mpz_srcptr get_den_mp() const { - return mpq_denref(get_mp()); - } - /// return mpz pointer of denominator - mpz_ptr get_den_mp() { - return mpq_denref(get_mp()); + inline BigInt denominator(const BigRat& q) + { + return boost::multiprecision::denominator(q); } - /// get mpq pointer (const) - mpq_srcptr get_mp() const { - return rep->get_mp(); - } - /// get mpq pointer - mpq_ptr get_mp() { - return rep->get_mp(); - } - //@} - - /// \name String Conversion Functions - //@{ - /// set value from const char* - int set_str(const char* s, int base = 0) { - makeCopy(); - return mpq_set_str(get_mp(), s, base); - } - /// convert to std::string - std::string get_str(int base = 10) const { - int n = mpz_sizeinbase(mpq_numref(get_mp()), base) + mpz_sizeinbase(mpq_denref(get_mp()), base)+ 3; - char *buffer = new char[n]; - mpq_get_str(buffer, base, get_mp()); - std::string result(buffer); - delete [] buffer; - return result; - } - //@} - - /// \name Conversion Functions - //@{ - /// intValue - int intValue() const { - return static_cast(doubleValue()); - } - /// longValue - long longValue() const { - return static_cast(doubleValue()); - } - /// doubleValue - double doubleValue() const { - return mpq_get_d(get_mp()); - } - /// BigIntValue - BigInt BigIntValue() const { - BigInt r; - mpz_tdiv_q(r.get_mp(), get_num_mp(), get_den_mp()); - return r; - } - //@} -}; //BigRat class - -inline BigRat operator+(const BigRat& a, const BigRat& b) { - BigRat r; - mpq_add(r.get_mp(), a.get_mp(), b.get_mp()); - return r; -} -inline BigRat operator-(const BigRat& a, const BigRat& b) { - BigRat r; - mpq_sub(r.get_mp(), a.get_mp(), b.get_mp()); - return r; -} -inline BigRat operator*(const BigRat& a, const BigRat& b) { - BigRat r; - mpq_mul(r.get_mp(), a.get_mp(), b.get_mp()); - return r; -} -inline BigRat operator/(const BigRat& a, const BigRat& b) { - BigRat r; - mpq_div(r.get_mp(), a.get_mp(), b.get_mp()); - return r; -} -// Chee (3/19/2004): + // Chee (3/19/2004): // The following definitions of div_exact(x,y) and gcd(x,y) // ensures that in Polynomial /// divisible(x,y) = "x | y" -inline BigRat div_exact(const BigRat& x, const BigRat& y) { - BigRat z; - mpq_div(z.get_mp(), x.get_mp(), y.get_mp()); - return z; -} -/// numerator -inline BigInt numerator(const BigRat& a) { - return BigInt(a.get_num_mp()); -} -/// denominator -inline BigInt denominator(const BigRat& a) { - return BigInt(a.get_den_mp()); -} + inline BigRat div_exact(const BigRat& x, const BigRat& y) { + BigRat z = x / y; + return z; + } -inline BigRat gcd(const BigRat& x, const BigRat& y) { - // return BigRat(1); // Remark: we may want replace this by + inline BigRat gcd(const BigRat& x , const BigRat& y) + { + // return BigRat(1); // Remark: we may want replace this by // the definition of gcd of a quotient field // of a UFD [Yap's book, Chap.3] //Here is one possible definition: gcd of x and y is just the @@ -384,98 +65,17 @@ inline BigRat gcd(const BigRat& x, const BigRat& y) { BigInt n = gcd(numerator(x), numerator(y)); BigInt d = gcd(denominator(x), denominator(y)); return BigRat(n,d); + } -} -// Chee: 8/8/2004: need isDivisible to compile Polynomial -// A trivial implementation is to return true always. But this -// caused tPolyRat to fail. -// So we follow the definition of -// Expr::isDivisible(e1, e2) which checks if e1/e2 is an integer. -inline bool isInteger(const BigRat& x) { - return BigInt(x.get_den_mp()) == 1; -} -inline bool isDivisible(const BigRat& x, const BigRat& y) { - BigRat r; - mpq_div(r.get_mp(), x.get_mp(), y.get_mp()); - return isInteger(r); -} -inline BigRat operator<<(const BigRat& a, unsigned long ul) { - BigRat r; - mpq_mul_2exp(r.get_mp(), a.get_mp(), ul); - return r; -} -inline BigRat operator>>(const BigRat& a, unsigned long ul) { - BigRat r; - mpq_div_2exp(r.get_mp(), a.get_mp(), ul); + /// BigIntValue +inline BigInt BigIntValue(const BigRat& br) +{ + BigInt r, rem; + divide_qr(numerator(br), denominator(br), r, rem); return r; } -inline int cmp(const BigRat& x, const BigRat& y) { - return mpq_cmp(x.get_mp(), y.get_mp()); -} -inline bool operator==(const BigRat& a, const BigRat& b) { - return cmp(a, b) == 0; -} -inline bool operator!=(const BigRat& a, const BigRat& b) { - return cmp(a, b) != 0; -} -inline bool operator>=(const BigRat& a, const BigRat& b) { - return cmp(a, b) >= 0; -} -inline bool operator>(const BigRat& a, const BigRat& b) { - return cmp(a, b) > 0; -} -inline bool operator<=(const BigRat& a, const BigRat& b) { - return cmp(a, b) <= 0; -} -inline bool operator<(const BigRat& a, const BigRat& b) { - return cmp(a, b) < 0; -} - -inline std::ostream& operator<<(std::ostream& o, const BigRat& x) { - //return CORE::operator<<(o, x.get_mp()); - return CORE::io_write(o, x.get_mp()); -} -inline std::istream& operator>>(std::istream& i, BigRat& x) { - x.makeCopy(); - //return CORE::operator>>(i, x.get_mp()); - return CORE::io_read(i, x.get_mp()); -} - -/// sign -inline int sign(const BigRat& a) { - return mpq_sgn(a.get_mp()); -} -/// abs -inline BigRat abs(const BigRat& a) { - BigRat r; - mpq_abs(r.get_mp(), a.get_mp()); - return r; -} -/// neg -inline BigRat neg(const BigRat& a) { - BigRat r; - mpq_neg(r.get_mp(), a.get_mp()); - return r; -} -/// div2 -inline BigRat div2(const BigRat& a) { - BigRat r(a); - return r.div2(); -} -/// longValue -inline long longValue(const BigRat& a) { - return a.longValue(); -} -/// doubleValue -inline double doubleValue(const BigRat& a) { - return a.doubleValue(); -} -/// return BigInt value -inline BigInt BigIntValue(const BigRat& a) { - return a.BigIntValue(); -} +} // namespace CORE -} //namespace CORE #endif // _CORE_BIGRAT_H_ diff --git a/CGAL_Core/include/CGAL/CORE/Config.h b/CGAL_Core/include/CGAL/CORE/Config.h index b85ddbf55384..9f49a7f59860 100644 --- a/CGAL_Core/include/CGAL/CORE/Config.h +++ b/CGAL_Core/include/CGAL/CORE/Config.h @@ -29,4 +29,13 @@ #include +#ifdef CGAL_TEST_SUITE +// disabled for the testsuite to avoid `w` +#define CGAL_CORE_warning_msg(X ,Y) +// if (!(X)) CGAL_error_msg(Y) +#else +#define CGAL_CORE_warning_msg(X ,Y) CGAL_warning_msg(X ,Y) +#endif + + #endif // _CORE_CONFIG_H_ diff --git a/CGAL_Core/include/CGAL/CORE/CoreAux.h b/CGAL_Core/include/CGAL/CORE/CoreAux.h index 8577514dac03..b90d25656bfa 100644 --- a/CGAL_Core/include/CGAL/CORE/CoreAux.h +++ b/CGAL_Core/include/CGAL/CORE/CoreAux.h @@ -156,12 +156,6 @@ CGAL_CORE_EXPORT double IntMantissa(double d); // (See CORE_PATH/progs/ieee/frexp.cpp for details) CGAL_CORE_EXPORT int IntExponent(double d); -/// Writes out an error or warning message in the local file CORE_DIAGFILE -/** If last argument (err) is TRUE, then this is considered an error - * (not just warning). In this case, the message is also printed in - * std::cerr, using std::perror(). - * */ -CGAL_CORE_EXPORT void core_error(std::string msg, std::string file, int lineno, bool err); /// This is for debugging messages inline void core_debug(std::string msg){ diff --git a/CGAL_Core/include/CGAL/CORE/CoreAux_impl.h b/CGAL_Core/include/CGAL/CORE/CoreAux_impl.h index 9b335c393b27..434978c83250 100644 --- a/CGAL_Core/include/CGAL/CORE/CoreAux_impl.h +++ b/CGAL_Core/include/CGAL/CORE/CoreAux_impl.h @@ -31,7 +31,6 @@ #include #include -#include namespace CORE { @@ -157,30 +156,5 @@ int IntExponent(double d) { return e-53; } -/// core_error is the method to write Core Library warning or error messages -/** Both warnings and errors are written to a file called CORE_DIAGFILE. - * But errors are also written on std::cerr (similar to std::perror()). - * */ -// Usage: core_error(message, file_with_error, line_number, err_type) -// where err_type=0 means WARNING, error_type=0 means ERROR -CGAL_INLINE_FUNCTION -void core_error(std::string msg, std::string file, int lineno, bool err) { - std::ofstream outFile(CORE_DIAGFILE, std::ios::app); // open to append - if (!outFile) { - // perror("CORE ERROR: cannot open Core Diagnostics file"); - std::cerr << "CORE ERROR: can't open Core Diagnostics file"< - * Chee Yap - * - * WWW URL: https://cs.nyu.edu/exact/ - * Email: exact@cs.nyu.edu - * - * $URL$ - * $Id$ - * SPDX-License-Identifier: LGPL-3.0-or-later - ***************************************************************************/ - -#ifndef _COREIO_IMPL_H_ -#define _COREIO_IMPL_H_ - -#ifdef CGAL_HEADER_ONLY -#define CGAL_INLINE_FUNCTION inline -#else -#define CGAL_INLINE_FUNCTION -#endif - -#include -#include -#include - -namespace CORE { - -CGAL_INLINE_FUNCTION -void core_io_error_handler(const char *f, const char *m) { - std::cout << "\n error_handler"; - std::cout << "::" << f << "::" << m << "\n"; - std::cout.flush(); - std::abort(); -} - -CGAL_INLINE_FUNCTION -void core_io_memory_handler(char *t, const char *f, const char *m) { - if (t == nullptr) { - std::cout << "\n memory_handler"; - std::cout << "::" << f << "::" << m; - std::cout << "memory exhausted\n"; - std::cout.flush(); - std::abort(); - } -} - -// s has size old_size and will be resized to new_size. -CGAL_INLINE_FUNCTION -void allocate (char * &s, int old_size, int new_size) { - if (old_size > new_size) - old_size = new_size; - - if (s == nullptr) - old_size = 0; - - char *t = new char[new_size]; - core_io_memory_handler(t, "CoreIO", "allocate::out of memory error"); - - int i; - for (i = 0; i < old_size; i++) - t[i] = s[i]; - - delete[] s; - s = t; -} - -// appends c to s at position pos. -// sz is the size of s -CGAL_INLINE_FUNCTION -void append_char (char * &s, int & sz, int pos, char c) { - if (pos > sz) - core_io_error_handler("CoreIO", "append_char::invalid argument"); - - if (pos == sz) { - allocate(s, sz, 2*sz); - sz *= 2; - } - - s[pos] = c; -} - -// skip blanks, tabs, line breaks and comment lines -CGAL_INLINE_FUNCTION -int skip_comment_line (std::istream & in) { - char c; - - do { - in.get(c); - while ( c == '#' ) { - do { - in.get(c); - } while ( c != '\n' ); - in.get(c); - } - } while (c == ' ' || c == '\t' || c == '\n'); - - if (in.eof()) - core_io_error_handler("CoreIO::read_from_file()","unexpected end of file."); - - in.putback(c); - return c; -} - -// skips '\\' followed by '\n' -CGAL_INLINE_FUNCTION -char skip_backslash_new_line (std::istream & in) { - char c; - in.get(c); - - while (c == '\\') { - in.get(c); - - if (c == '\n') - in.get(c); - else - core_io_error_handler("CoreIO::operator>>", "\\ must be immediately followed by new line."); - } - - return c; -} - -CGAL_INLINE_FUNCTION -void read_string(std::istream& in, char* &buffer, int sz) { - char c; - int pos=0; - skip_comment_line(in); - - while ( in.get(c) ) { - if ( c == ' ' || c == '\t' || c == '\n' || c == '#') - break; - else - append_char(buffer, sz, pos++, c); - } - append_char(buffer, sz, pos, '\0'); -} - -CGAL_INLINE_FUNCTION -void read_base_number(std::istream& in, BigInt& m, long length, long maxBits) { - char *buffer; - int size, offset; - int base; - bool is_negate; - - char c; - int pos = 0; - skip_comment_line(in); - - // read sign - in.get(c); - if (c == '-') { - is_negate = true; - in.get(c); - } else - is_negate = false; - - // read base and compute digits - if (c == '0') { - in.get(c); - if (c == 'b') { - base = 2; - size = (maxBits == 0 || maxBits > length) ? length : maxBits; - offset = length - size; - } else if (c == 'x') { - base = 16; - size = (maxBits == 0) ? length : (maxBits+3) >> 2; - size = (size > length) ? length : size; - offset = (length - size) << 2; - } else { - base = 8; - size = (maxBits == 0) ? length : (maxBits+2) / 3; - size = (size > length) ? length : size; - offset = (length - size) * 3; - in.putback(c); - } - } else { - base = 10; - size = (maxBits == 0) ? length : (int)std::ceil(maxBits*std::log(2.0)/std::log(10.0)); - size = (size > length) ? length : size; - offset = length - size; - in.putback(c); - } - - buffer = new char[size+2]; - // read digits - for (int i=0; i 0 && base != 10) { - m <<= offset; - } - - if (is_negate) - negate(m); -} - - -CGAL_INLINE_FUNCTION -void write_base_number(std::ostream& out, char* buffer, std::size_t length, int base, int charsPerLine) { - // write big number in a format that gmp's mpz_set_str() can - // automatically recognize with argument base = 0. - if (base == 2) - out << "0b"; - else if (base == 16) - out << "0x"; - else if (base == 8) - out << '0'; - - // write big number in charsPerLine. - char* start, *end, c; - for (std::size_t i=0; i= length) - out << start; - else { - end = start + charsPerLine; - c = *end; - *end = '\0'; - - out << start << "\\\n"; - *end = c; - } - } -} - -CGAL_INLINE_FUNCTION -void readFromFile(BigInt& z, std::istream& in, long maxLength) { - char *buffer; - long length; - - // check type name whether it is Integer or not. - buffer = new char[8]; - read_string(in, buffer, sizeof(buffer)); - if ( std::strcmp(buffer, "Integer") != 0) - core_io_error_handler("BigInt::read_from_file()","type name expected."); - delete[] buffer; - - // read the bit length field. - buffer = new char[100]; - read_string(in, buffer, sizeof(buffer)); - length = std::atol(buffer); - delete[] buffer; - - // read bigint - read_base_number(in, z, length, maxLength); -} - -CGAL_INLINE_FUNCTION -void writeToFile(const BigInt& z, std::ostream& out, int base, int charsPerLine) { - BigInt c = abs(z); - - // get the absolute value string - char* buffer = new char[mpz_sizeinbase(c.get_mp(), base) + 2]; - mpz_get_str(buffer, base, c.get_mp()); - std::size_t length = std::strlen(buffer); - - // write type name of big number and length - //out << "# This is an experimental big number format.\n"; - out << "Integer " << length << "\n"; - - // if bigint is negative, then write an sign '-'. - if ( sign(z) < 0 ) - out << '-'; - - write_base_number(out, buffer, length, base, charsPerLine); - out << "\n"; - delete[] buffer; -} - -CGAL_INLINE_FUNCTION -void readFromFile(BigFloat& bf, std::istream& in, long maxLength) { - char *buffer; - long length; - long exponent; - BigInt mantissa; - - // check type name whether it is Float - buffer = new char[6]; - read_string(in, buffer, sizeof(buffer)); - if (std::strcmp(buffer, "Float") != 0) - core_io_error_handler("BigFloat::read_from_file()", "type name expected"); - delete[] buffer; - - // read base (default is 16384) - buffer = new char[8]; - read_string(in, buffer, sizeof(buffer)); - if (std::strcmp(buffer, "(16384)") != 0) - core_io_error_handler("BigFloat::read_from_file()", "base expected"); - delete[] buffer; - - // read the bit length field. - buffer = new char[100]; - read_string(in, buffer, sizeof(buffer)); - length = std::atol(buffer); - delete[] buffer; - - // read exponent - buffer = new char[100]; - read_string(in, buffer, sizeof(buffer)); - exponent = std::atol(buffer); - delete[] buffer; - - // read mantissa - read_base_number(in, mantissa, length, maxLength); - - // construct BigFloat - bf = BigFloat(mantissa, 0, exponent); -} - -CGAL_INLINE_FUNCTION -void writeToFile(const BigFloat& bf, std::ostream& out, int base, int charsPerLine) { - BigInt c(CORE::abs(bf.m())); - - // get the absolute value string - char* buffer = new char[mpz_sizeinbase(c.get_mp(), base) + 2]; - mpz_get_str(buffer, base, c.get_mp()); - std::size_t length = std::strlen(buffer); - - - // write type name, base, length - //out << "# This is an experimental Big Float format." << std::endl; - out << "Float (16384) " << length << std::endl; - // write exponent - out << bf.exp() << std::endl; - - // write mantissa - if ( CORE::sign(bf.m()) < 0 ) - out << '-'; - - write_base_number(out, buffer, length, base, charsPerLine); - out << '\n'; - delete[] buffer; -} - -/* Underconstruction ---- -void BigFloat::read_from_file2(std::istream& in, long maxLength) { - long length = 1024; - char *buffer; - - // check type name whether it is Float - buffer = new char[7]; - BigInt::read_string(in, buffer, sizeof(buffer)); - if (strcmp(buffer, "NFloat") != 0) - core_io_error_handler("BigFloat::read_from_file2()", "type name expected"); - delete[] buffer; - - // read base (default is 16) - buffer = new char[5]; - BigInt::read_string(in, buffer, sizeof(buffer)); - if (strcmp(buffer, "(16)") != 0) - core_io_error_handler("BigFloat::read_from_file2()", "base expected"); - delete[] buffer; - - // read length field - buffer = new char[100]; - BigInt::read_string(in, buffer, sizeof(buffer)); - - // get the length field if it is not null. - if (buffer[0] != '\0') { - length = atol(buffer); - if (maxLength > 0 && length >= maxLength) - length = maxLength; - } - delete[] buffer; - - // read exponent - buffer = new char[100]; - BigInt::read_string(in, buffer, sizeof(buffer)); - long exp16 = atol(buffer); - delete[] buffer; - - // read mantissa - buffer = new char[length+2]; - //BigInt::read_base_number(in, buffer, length); - - BigInt m16(buffer); - delete[] buffer; - - // convert to base CHUNK_BIT - exp16 = exp16 - length + 1; - if ( m16.is_negative() ) - exp16 ++; - - long tmp_exp = exp16 * 4; - long q = tmp_exp / CHUNK_BIT; - long r = tmp_exp % CHUNK_BIT; - if ( r < 0 ) { - r += CHUNK_BIT; - q --; - } - - BigInt mantissa = m16 << r; - long exponent = q; - - // construct BigFloat - if (--rep->refCount == 0) - delete rep; - - rep = new BigFloatRep(mantissa, 0, exponent); - rep->refCount++; - -} - -// write normal float -// now it assumed to write in hex base, i.e. B=2^4=16 -// (note: our default base B=2^(CHUNK_BIT)=2^14=16384 -void BigFloat::write_to_file2(std::ostream& out, int base, int charsPerLine) { - // convert to base 16. - long new_base = 4; // 2^4 = 16 - long tmp_exp = (rep->exp) * CHUNK_BIT; - long q = tmp_exp / new_base; - long r = tmp_exp % new_base; - std::cout << "CORE_DEBUG: q=" << q << ", r=" << r << std::endl; - if ( r < 0 ) { - r += new_base; - q--; - } - std::cout << "CORE_DEBUG: q=" << q << ", r=" << r << std::endl; - - BigInt m16 = (rep->m) << r; - - int size = mpz_sizeinbase(m16.I, base) + 2; - std::cout << "size=" << size << std::endl; - char* buffer = new char[size]; - - int length = bigint_to_string(m16, buffer, base); - std::cout << "length=" << length << std::endl; - - long exp16 = q + length - 1; - if ( m16.is_negative() ) - exp16 --; - - // write type name, base, length - out << "# This is an experimental Big Float format." << std::endl; - out << "NFloat (16) " << length << std::endl; - - // write exponent - out << exp16 << std::endl; - - // write mantissa - if ( m16.is_negative() ) { - out << '-'; - buffer ++; - } - - BigInt::write_base_number(out, buffer, length, base, charsPerLine); - out << '\n'; - delete[] buffer; -} -*/ - -} //namespace CORE - -#endif // _COREIO_IMPL_H_ diff --git a/CGAL_Core/include/CGAL/CORE/Expr.h b/CGAL_Core/include/CGAL/CORE/Expr.h index 39c1fb84a4c7..e6efa1feb7cf 100644 --- a/CGAL_Core/include/CGAL/CORE/Expr.h +++ b/CGAL_Core/include/CGAL/CORE/Expr.h @@ -72,9 +72,7 @@ class Expr : public RCExpr { Expr(float f) : RCExpr(nullptr) { // check for valid numbers // (i.e., not infinite and not NaN) if (! CGAL_CORE_finite(f)) { - core_error(" ERROR : constructed an invalid float! ", __FILE__, __LINE__, false); - if (get_static_AbortFlag()) - abort(); + CGAL_error_msg("ERROR : constructed an invalid float! "); get_static_InvalidFlag() = -1; } rep = new ConstDoubleRep(f); @@ -83,9 +81,7 @@ class Expr : public RCExpr { Expr(double d) : RCExpr(nullptr) { // check for valid numbers // (i.e., not infinite and not NaN) if (! CGAL_CORE_finite(d)) { - core_error(" ERROR : constructed an invalid double! ", __FILE__, __LINE__, false); - if (get_static_AbortFlag()) - abort(); + CGAL_error_msg("ERROR : constructed an invalid double! "); get_static_InvalidFlag() = -2; } rep = new ConstDoubleRep(d); @@ -95,6 +91,14 @@ class Expr : public RCExpr { Expr(const BigInt& I) : RCExpr(new ConstRealRep(Real(I))) {} /// constructor for BigRat Expr(const BigRat& R) : RCExpr(new ConstRealRep(Real(R))) {} + /// constructor from expression template + template ::value> > + Expr(const TmplExpr& R) + : RCExpr(new ConstRealRep(Real( + std::conditional_t::value == boost::multiprecision::number_kind_integer, + BigInt, BigRat>(R)))) {} /// constructor for BigFloat Expr(const BigFloat& F) : RCExpr(new ConstRealRep(Real(F))) {} @@ -173,9 +177,7 @@ class Expr : public RCExpr { /// /= operator Expr& operator/=(const Expr& e) { if ((e.rep)->getSign() == 0) { - core_error(" ERROR : division by zero ! ",__FILE__, __LINE__, false); - if (get_static_AbortFlag()) - abort(); + CGAL_error_msg("ERROR : division by zero ! "); get_static_InvalidFlag() = -3; } *this = new DivRep(rep, e.rep); @@ -376,9 +378,7 @@ inline Expr operator*(const Expr& e1, const Expr& e2) { /// division inline Expr operator/(const Expr& e1, const Expr& e2) { if (e2.sign() == 0) { - core_error(" ERROR : division by zero ! ", __FILE__, __LINE__, false); - if (get_static_AbortFlag()) - abort(); + CGAL_error_msg("ERROR : division by zero ! "); get_static_InvalidFlag() = -4; } return Expr(new DivRep(e1.Rep(), e2.Rep())); @@ -479,9 +479,7 @@ inline bool isDivisible(const Expr& e1, const Expr& e2) { /// square root inline Expr sqrt(const Expr& e) { if (e.sign() < 0) { - core_error(" ERROR : sqrt of negative value ! ", __FILE__, __LINE__, false); - if (get_static_AbortFlag()) - abort(); + CGAL_error_msg("ERROR : sqrt of negative value ! "); get_static_InvalidFlag() = -5; } return Expr(new SqrtRep(e.Rep())); diff --git a/CGAL_Core/include/CGAL/CORE/ExprRep.h b/CGAL_Core/include/CGAL/CORE/ExprRep.h index 7e4b56557ec4..0e721dda16a8 100644 --- a/CGAL_Core/include/CGAL/CORE/ExprRep.h +++ b/CGAL_Core/include/CGAL/CORE/ExprRep.h @@ -564,9 +564,7 @@ class CGAL_CORE_EXPORT ConstPolyRep : public ConstRep { I = ss.isolateRoot(n); // check whether n-th root exists if (I.first == 1 && I.second == 0) { - core_error("CORE ERROR! root index out of bound", - __FILE__, __LINE__, true); - abort(); + CGAL_error_msg("CORE ERROR! root index out of bound"); } // test if the root isolated in I is 0: if ((I.first == 0)&&(I.second == 0)) @@ -583,9 +581,7 @@ class CGAL_CORE_EXPORT ConstPolyRep : public ConstRep { ss.isolateRoots(I.first, I.second, v); I = v.front(); if (v.size() != 1) { - core_error("CORE ERROR! non-isolating interval", - __FILE__, __LINE__, true); - abort(); + CGAL_error_msg("CORE ERROR! non-isolating interval"); } ffVal = computeFilteredValue(); // Chee: this line seems unnecessary } @@ -1092,8 +1088,7 @@ void AddSubRep::computeExactFlags() { uMSB() = newValue.uMSB(); // chen: to get tighers value. sign() = newValue.sign(); } else if (lowBound.isInfty()) {//check if rootbound is too big - core_error("AddSubRep:root bound has exceeded the maximum size\n \ - but we still cannot decide zero.\n", __FILE__, __LINE__, false); + CGAL_CORE_warning_msg(false, "AddSubRep:root bound has exceeded the maximum size but we still cannot decide zero."); } else { // Op(first, second) == 0 lMSB() = CORE_negInfty; sign() = 0; @@ -1186,8 +1181,7 @@ void AddSubRep::computeExactFlags() { //8/9/01, Chee: implement escape precision here: if (i> get_static_EscapePrec()) { get_static_EscapePrecFlag() = -i.asLong();//negative means EscapePrec is used - core_error("Escape precision triggered at", - __FILE__, __LINE__, false); + CGAL_CORE_warning_msg(false, "Escape precision triggered"); if (get_static_EscapePrecWarning()) std::cout<< "Escape Precision triggered at " << get_static_EscapePrec() << " bits" << std::endl; @@ -1204,8 +1198,7 @@ void AddSubRep::computeExactFlags() { #endif if (sign() == 0 && ua .isInfty()) { - core_error("AddSubRep: root bound has exceeded the maximum size\n \ - but we still cannot decide zero.\n", __FILE__, __LINE__, true); + CGAL_error_msg("AddSubRep: root bound has exceeded the maximum size but we still cannot decide zero."); } // if (sign == 0 && ua .isInfty()) }// else do progressive } @@ -1236,8 +1229,7 @@ void AddSubRep::computeApproxValue(const extLong& relPrec, { std::ostringstream oss; oss << "CORE WARNING: a huge lMSB in AddSubRep: " << lMSB(); - core_error(oss.str(), - __FILE__, __LINE__, false); + CGAL_CORE_warning_msg(false, oss.str().c_str()); } extLong rf = first->uMSB()-lMSB()+relPrec+EXTLONG_FOUR; // 2 better diff --git a/CGAL_Core/include/CGAL/CORE/Expr_impl.h b/CGAL_Core/include/CGAL/CORE/Expr_impl.h index 2c643aa402a0..0a36d169cf5c 100644 --- a/CGAL_Core/include/CGAL/CORE/Expr_impl.h +++ b/CGAL_Core/include/CGAL/CORE/Expr_impl.h @@ -702,7 +702,7 @@ void computeExactFlags_temp(ConstRep* t, const Real &value) { } else { t->uMSB() = value.uMSB(); t->lMSB() = value.lMSB(); - core_error("Leaves in DAG is not exact!", __FILE__, __LINE__, true); + CGAL_error_msg("Leafs in DAG is not exact!"); } t->sign() = value.sign(); @@ -809,8 +809,7 @@ void SqrtRep::computeExactFlags() { sign() = child->sign(); if (sign() < 0) - core_error("squareroot is called with negative operand.", - __FILE__, __LINE__, true); + CGAL_error_msg("square root is called with negative operand."); uMSB() = child->uMSB() / EXTLONG_TWO; lMSB() = child->lMSB() / EXTLONG_TWO; @@ -928,7 +927,7 @@ void DivRep::computeExactFlags() { second->computeExactFlags(); if (!second->sign()) - core_error("zero divisor.", __FILE__, __LINE__, true); + CGAL_error_msg("zero divisor."); if (!first->sign()) {// value must be exactly zero. reduceToZero(); @@ -1025,8 +1024,7 @@ void MultRep::computeApproxValue(const extLong& relPrec, { std::ostringstream oss; oss << "CORE WARNING: a huge lMSB in AddSubRep " << lMSB(); - core_error(oss.str(), - __FILE__, __LINE__, false); + CGAL_CORE_warning_msg(false, oss.str().c_str()); } extLong r = relPrec + EXTLONG_FOUR; @@ -1048,8 +1046,7 @@ void DivRep::computeApproxValue(const extLong& relPrec, { std::ostringstream oss; oss << "CORE WARNING: a huge lMSB in AddSubRep " << lMSB(); - core_error(oss.str(), - __FILE__, __LINE__, false); + CGAL_CORE_warning_msg(false, oss.str().c_str()); } extLong rr = relPrec + EXTLONG_SEVEN; // These rules come from @@ -1082,7 +1079,9 @@ void Expr::debug(int mode, int level, int depthLimit) const { else if (mode == Expr::TREE_MODE) rep->debugTree(level, 0, depthLimit); else - core_error("unknown debugging mode", __FILE__, __LINE__, false); + { + CGAL_CORE_warning_msg(false, "unknown debugging mode"); + } std::cout << "---- End Expr debug(): " << std::endl; } @@ -1215,8 +1214,6 @@ void BinOpRep::debugTree(int level, int indent, int depthLimit) const { second->debugTree(level, indent + 2, depthLimit - 1); } -CORE_MEMORY_IMPL(BigIntRep) -CORE_MEMORY_IMPL(BigRatRep) CORE_MEMORY_IMPL(ConstDoubleRep) CORE_MEMORY_IMPL(ConstRealRep) diff --git a/CGAL_Core/include/CGAL/CORE/Filter.h b/CGAL_Core/include/CGAL/CORE/Filter.h index 56649b80c864..e71c8aa8733f 100644 --- a/CGAL_Core/include/CGAL/CORE/Filter.h +++ b/CGAL_Core/include/CGAL/CORE/Filter.h @@ -137,8 +137,8 @@ class filteredFp { } /// division filteredFp operator/ (const filteredFp& x) const { - if (x.fpVal == 0.0) - core_error("possible zero divisor!", __FILE__, __LINE__, false); + CGAL_CORE_warning_msg(x.fpVal != 0.0, "possible zero divisor!"); + double xxx = core_abs(x.fpVal) / x.maxAbs - (x.ind+1)*CORE_EPS + DBL_MIN; if (xxx > 0) { double val = fpVal / x.fpVal; @@ -149,8 +149,8 @@ class filteredFp { } /// square root filteredFp sqrt () const { - if (fpVal < 0.0) - core_error("possible negative sqrt!", __FILE__, __LINE__, false); + + CGAL_CORE_warning_msg( !(fpVal < 0.0), "possible negative sqrt!"); if (fpVal > 0.0) { double val = std::sqrt(fpVal); return filteredFp(val, ( maxAbs / fpVal ) * val, 1 + ind); diff --git a/CGAL_Core/include/CGAL/CORE/Gmp.h b/CGAL_Core/include/CGAL/CORE/Gmp.h deleted file mode 100644 index 4febe840d9ac..000000000000 --- a/CGAL_Core/include/CGAL/CORE/Gmp.h +++ /dev/null @@ -1,37 +0,0 @@ -/**************************************************************************** - * Core Library Version 1.7, August 2004 - * Copyright (c) 1995-2004 Exact Computation Project - * All rights reserved. - * - * This file is part of CGAL (www.cgal.org). - * - * $URL$ - * $Id$ - * SPDX-License-Identifier: LGPL-3.0-or-later - ***************************************************************************/ - -// CORE LIBRARY FILE -#ifndef _CORE_GMP_H_ -#define _CORE_GMP_H_ - -#include -#include - -namespace CORE { - -CGAL_CORE_EXPORT std::ostream& io_write (std::ostream &, mpz_srcptr); -CGAL_CORE_EXPORT std::ostream& io_write (std::ostream &, mpq_srcptr); -CGAL_CORE_EXPORT std::istream& io_read (std::istream &, mpz_ptr); -CGAL_CORE_EXPORT std::istream& io_read (std::istream &, mpq_ptr); -//std::ostream& operator<< (std::ostream &, mpz_srcptr); -//std::ostream& operator<< (std::ostream &, mpq_srcptr); -//std::istream& operator>> (std::istream &, mpz_ptr); -//std::istream& operator>> (std::istream &, mpq_ptr); - -} //namespace CORE - -#ifdef CGAL_HEADER_ONLY -#include -#endif // CGAL_HEADER_ONLY - -#endif // _CORE_GMP_H_ diff --git a/CGAL_Core/include/CGAL/CORE/Gmp_impl.h b/CGAL_Core/include/CGAL/CORE/Gmp_impl.h deleted file mode 100644 index 479dc0dd0faf..000000000000 --- a/CGAL_Core/include/CGAL/CORE/Gmp_impl.h +++ /dev/null @@ -1,265 +0,0 @@ -/**************************************************************************** - * Core Library Version 1.7, August 2004 - * Copyright (c) 1995-2004 Exact Computation Project - * All rights reserved. - * - * file: GmpIO.cpp - * Adapted from multi-files under /cxx in GMP's source distribution - * - * Zilin Du, 2003 - * - * $URL$ - * $Id$ - * SPDX-License-Identifier: LGPL-3.0-only - ***************************************************************************/ - -/* Auxiliary functions for C++-style input of GMP types. - -Copyright 2001 Free Software Foundation, Inc. - -This file is part of the GNU MP Library. - -*/ - -#ifdef CGAL_HEADER_ONLY -#define CGAL_INLINE_FUNCTION inline -#else -#define CGAL_INLINE_FUNCTION -#endif - -#include -#include -#include -#include -#include - -namespace CORE { - -CGAL_INLINE_FUNCTION -int -__gmp_istream_set_base (std::istream &i, char &c, bool &zero, bool &showbase) -{ - int base; - using std::ios; - - zero = showbase = false; - switch (i.flags() & ios::basefield) - { - case ios::dec: - base = 10; - break; - case ios::hex: - base = 16; - break; - case ios::oct: - base = 8; - break; - default: - showbase = true; // look for initial "0" or "0x" or "0X" - if (c == '0') - { - if (! i.get(c)) - c = 0; // reset or we might loop indefinitely - - if (c == 'x' || c == 'X') - { - base = 16; - i.get(c); - } - else - { - base = 8; - zero = true; // if no other digit is read, the "0" counts - } - } - else - base = 10; - break; - } - - return base; -} - -CGAL_INLINE_FUNCTION -void -__gmp_istream_set_digits (std::string &s, std::istream &i, char &c, bool &ok, int base) -{ - switch (base) - { - case 10: - while (isdigit(c)) - { - ok = true; // at least a valid digit was read - s += c; - if (! i.get(c)) - break; - } - break; - case 8: - while (isdigit(c) && c != '8' && c != '9') - { - ok = true; // at least a valid digit was read - s += c; - if (! i.get(c)) - break; - } - break; - case 16: - while (isxdigit(c)) - { - ok = true; // at least a valid digit was read - s += c; - if (! i.get(c)) - break; - } - break; - } -} - -CGAL_INLINE_FUNCTION -std::istream & -//operator>> (std::istream &i, mpz_ptr z) -io_read (std::istream &i, mpz_ptr z) -{ - using namespace std; - int base; - char c = 0; - std::string s; - bool ok = false, zero, showbase; - - i.get(c); // start reading - - if (i.flags() & ios::skipws) // skip initial whitespace - while (isspace(c) && i.get(c)) - ; - - if (c == '-' || c == '+') // sign - { - if (c == '-') // mpz_set_str doesn't accept '+' - s = "-"; - i.get(c); - } - - while (isspace(c) && i.get(c)) // skip whitespace - ; - - base = __gmp_istream_set_base(i, c, zero, showbase); // select the base - __gmp_istream_set_digits(s, i, c, ok, base); // read the number - - if (i.good()) // last character read was non-numeric - i.putback(c); - else if (i.eof() && (ok || zero)) // stopped just before eof - i.clear(); - - if (ok) - mpz_set_str(z, s.c_str(), base); // extract the number - else if (zero) - mpz_set_ui(z, 0); - else - i.setstate(ios::failbit); // read failed - - return i; -} - -CGAL_INLINE_FUNCTION -std::istream & -//operator>> (std::istream &i, mpq_ptr q) -io_read (std::istream &i, mpq_ptr q) -{ - using namespace std; - int base; - char c = 0; - std::string s; - bool ok = false, zero, showbase; - - i.get(c); // start reading - - if (i.flags() & ios::skipws) // skip initial whitespace - while (isspace(c) && i.get(c)) - ; - - if (c == '-' || c == '+') // sign - { - if (c == '-') - s = "-"; - i.get(c); - } - - while (isspace(c) && i.get(c)) // skip whitespace - ; - - base = __gmp_istream_set_base(i, c, zero, showbase); // select the base - __gmp_istream_set_digits(s, i, c, ok, base); // read the numerator - - if (! ok && zero) // the only digit read was "0" - { - base = 10; - s += '0'; - ok = true; - } - - if (c == '/') // there's a denominator - { - bool zero2 = false; - int base2 = base; - - s += '/'; - ok = false; // denominator is mandatory - i.get(c); - - while (isspace(c) && i.get(c)) // skip whitespace - ; - - if (showbase) // check base of denominator - base2 = __gmp_istream_set_base(i, c, zero2, showbase); - - if (base2 == base || base2 == 10) // read the denominator - __gmp_istream_set_digits(s, i, c, ok, base); - - if (! ok && zero2) // the only digit read was "0" - { // denominator is 0, but that's your business - s += '0'; - ok = true; - } - } - - if (i.good()) // last character read was non-numeric - i.putback(c); - else if (i.eof() && ok) // stopped just before eof - i.clear(); - - if (ok) - mpq_set_str(q, s.c_str(), base); // extract the number - else - i.setstate(ios::failbit); // read failed - - return i; -} - -CGAL_INLINE_FUNCTION -std::ostream& -//operator<< (std::ostream &o, mpz_srcptr z) -io_write (std::ostream &o, mpz_srcptr z) -{ - char *str = new char [mpz_sizeinbase(z,10) + 2]; - str = mpz_get_str(str, 10, z); - o << str ; - delete[] str; - return o; -} - -CGAL_INLINE_FUNCTION -std::ostream& -//operator<< (std::ostream &o, mpq_srcptr q) -io_write (std::ostream &o, mpq_srcptr q) -{ - // size according to GMP documentation - char *str = new char [mpz_sizeinbase(mpq_numref(q), 10) + - mpz_sizeinbase (mpq_denref(q), 10) + 3]; - str = mpq_get_str(str, 10, q); - o << str ; - delete[] str; - return o; -} - -} //namespace CORE diff --git a/CGAL_Core/include/CGAL/CORE/MemoryPool.h b/CGAL_Core/include/CGAL/CORE/MemoryPool.h index 60a95c862e22..2db3de8736e1 100644 --- a/CGAL_Core/include/CGAL/CORE/MemoryPool.h +++ b/CGAL_Core/include/CGAL/CORE/MemoryPool.h @@ -57,7 +57,7 @@ class MemoryPool { t = t->next; } //); - //CGAL_warning_msg(count == nObjects * blocks.size(), + //CGAL_CORE_warning_msg(count == nObjects * blocks.size(), // "Cannot delete memory as there are cyclic references"); if(count == nObjects * blocks.size()){ diff --git a/CGAL_Core/include/CGAL/CORE/Promote.h b/CGAL_Core/include/CGAL/CORE/Promote.h index d882b6abcf30..2bc334c959ad 100644 --- a/CGAL_Core/include/CGAL/CORE/Promote.h +++ b/CGAL_Core/include/CGAL/CORE/Promote.h @@ -26,10 +26,12 @@ * SPDX-License-Identifier: LGPL-3.0-or-later ***************************************************************************/ -#ifndef __PROMOTE_H__ -#define __PROMOTE_H__ +#ifndef _CORE_PROMOTE_H__ +#define _CORE_PROMOTE_H__ #include +#include +#include namespace CORE { @@ -67,10 +69,10 @@ class Promotion { typedef T ResultT; }; -#define MAX_TYPE(T1, T2) \ +#define CORE_MAX_TYPE(T1, T2) \ typename Promotion::ResultT -#define DEFINE_MAX_TYPE(T1, T2, Tr) \ +#define CORE_DEFINE_MAX_TYPE(T1, T2, Tr) \ template<> class Promotion { \ public: \ typedef Tr ResultT; \ @@ -83,15 +85,15 @@ class Promotion { /* * For example: * - * DEFINE_MAX_TYPE(BigInt, BigRat, BigRat) // define the promotion + * CORE_DEFINE_MAX_TYPE(BigInt, BigRat, BigRat) // define the promotion * * template // define function f with type templates - * MAX_TYPE(T1, T2) f(T1& , T2& ); + * CORE_MAX_TYPE(T1, T2) f(T1& , T2& ); * * or * * template // define function f with type templates - * const MAX_TYPE(T1, T2)& f(T1& , T2& ); + * const CORE_MAX_TYPE(T1, T2)& f(T1& , T2& ); * * BigInt a = 1; * BigRat b = "1/3"; @@ -119,30 +121,30 @@ class Promotion { * */ -class BigInt; +//class BigInt; class BigFloat; -class BigRat; +//class BigRat; class Expr; -DEFINE_MAX_TYPE(long, BigInt, BigInt) -DEFINE_MAX_TYPE(long, BigFloat, BigFloat) -DEFINE_MAX_TYPE(long, BigRat, BigRat) -DEFINE_MAX_TYPE(long, Expr, Expr) +CORE_DEFINE_MAX_TYPE(long, BigInt, BigInt) +CORE_DEFINE_MAX_TYPE(long, BigFloat, BigFloat) +CORE_DEFINE_MAX_TYPE(long, BigRat, BigRat) +CORE_DEFINE_MAX_TYPE(long, Expr, Expr) -DEFINE_MAX_TYPE(int, BigInt, BigInt) -DEFINE_MAX_TYPE(int, BigFloat, BigFloat) -DEFINE_MAX_TYPE(int, BigRat, BigRat) -DEFINE_MAX_TYPE(int, Expr, Expr) +CORE_DEFINE_MAX_TYPE(int, BigInt, BigInt) +CORE_DEFINE_MAX_TYPE(int, BigFloat, BigFloat) +CORE_DEFINE_MAX_TYPE(int, BigRat, BigRat) +CORE_DEFINE_MAX_TYPE(int, Expr, Expr) -DEFINE_MAX_TYPE(BigInt, BigFloat, BigFloat) -DEFINE_MAX_TYPE(BigInt, BigRat, BigRat) -DEFINE_MAX_TYPE(BigInt, Expr, Expr) +CORE_DEFINE_MAX_TYPE(BigInt, BigFloat, BigFloat) +CORE_DEFINE_MAX_TYPE(BigInt, BigRat, BigRat) +CORE_DEFINE_MAX_TYPE(BigInt, Expr, Expr) -DEFINE_MAX_TYPE(BigFloat, BigRat, BigRat) -DEFINE_MAX_TYPE(BigFloat, Expr, Expr) +CORE_DEFINE_MAX_TYPE(BigFloat, BigRat, BigRat) +CORE_DEFINE_MAX_TYPE(BigFloat, Expr, Expr) -DEFINE_MAX_TYPE(BigRat, Expr, Expr) +CORE_DEFINE_MAX_TYPE(BigRat, Expr, Expr) } //namespace CORE -#endif //__PROMOTE_H__ +#endif //_CORE_PROMOTE_H__ diff --git a/CGAL_Core/include/CGAL/CORE/Real.h b/CGAL_Core/include/CGAL/CORE/Real.h index dc4573cda206..6ca51cbf4490 100644 --- a/CGAL_Core/include/CGAL/CORE/Real.h +++ b/CGAL_Core/include/CGAL/CORE/Real.h @@ -277,12 +277,12 @@ const long halfLongMin = LONG_MIN /2; struct _real_add { template static Real eval(const T& a, const T& b) { - return a+b; + return T(a+b); } // specialized for two long values static Real eval(long a, long b) { if ((a > halfLongMax && b > halfLongMax) || (a < halfLongMin && b < halfLongMin)) - return BigInt(a)+BigInt(b); + return BigInt(BigInt(a)+ BigInt(b)); else return a+b; } @@ -291,12 +291,12 @@ struct _real_add { struct _real_sub { template static Real eval(const T& a, const T& b) { - return a-b; + return T(a-b); } // specialized for two long values static Real eval(long a, long b) { if ((a > halfLongMax && b < halfLongMin) || (a < halfLongMin && b > halfLongMax)) - return BigInt(a)-BigInt(b); + return BigInt(BigInt(a)-BigInt(b)); else return a-b; } @@ -305,12 +305,12 @@ struct _real_sub { struct _real_mul { template static Real eval(const T& a, const T& b) { - return a*b; + return T(a*b); } // specialized for two long values static Real eval(long a, long b) { if (flrLg(a) + flrLg(b) >= static_cast(LONG_BIT-2)) - return BigInt(a)*BigInt(b); + return BigInt(BigInt(a)*BigInt(b)); else return a*b; } @@ -357,7 +357,7 @@ struct real_div { bf_a.approx(a.BigRatValue(), bf_b.MSB() - bf_b.flrLgErr() + 1, CORE_posInfty); return bf_a.div(bf_b, r); } else // both are BigRat - return a.BigRatValue()/b.BigRatValue(); + return BigRat(a.BigRatValue() / b.BigRatValue()); } else if (a.ID() == REAL_BIGFLOAT || b.ID() == REAL_BIGFLOAT || a.ID() == REAL_DOUBLE || b.ID() == REAL_DOUBLE) { return a.BigFloatValue().div(b.BigFloatValue(), r); @@ -478,11 +478,11 @@ inline Real sqrt(const Real& x) { // unary minus operator template inline Real Realbase_for::operator-() const { - return -ker; + return T(- T(ker)); } template <> inline Real RealLong::operator-() const { - return ker < -LONG_MAX ? -BigInt(ker) : -ker; + return ker < -LONG_MAX ? BigInt(- BigInt(ker)) : -ker; } inline void init_CORE() { diff --git a/CGAL_Core/include/CGAL/CORE/RealRep.h b/CGAL_Core/include/CGAL/CORE/RealRep.h index 94602c2d1cb6..1c5d0f13a405 100644 --- a/CGAL_Core/include/CGAL/CORE/RealRep.h +++ b/CGAL_Core/include/CGAL/CORE/RealRep.h @@ -92,10 +92,10 @@ class Realbase_for : public RealRep { int ID() const; long longValue() const { - return ker.longValue(); + return CORE::longValue(ker); } double doubleValue() const { - return ker.doubleValue(); + return CORE::doubleValue(ker); } BigInt BigIntValue() const { return BigInt(ker); @@ -231,7 +231,7 @@ inline BigInt RealBigInt::BigIntValue() const { } template<> inline BigInt RealBigRat::BigIntValue() const { - return ker.BigIntValue(); + return CORE::BigIntValue(ker); } template<> inline BigInt RealBigFloat::BigIntValue() const { @@ -500,11 +500,11 @@ inline unsigned long RealBigRat::height() const { // toString() template<> inline std::string RealBigInt::toString(long, bool) const { - return ker.get_str(); + return ker.convert_to(); } template<> inline std::string RealBigRat::toString(long, bool) const { - return ker.get_str(); + return ker.convert_to(); } template<> inline std::string RealBigFloat::toString(long prec, bool sci) const { diff --git a/CGAL_Core/include/CGAL/CORE/extLong.h b/CGAL_Core/include/CGAL/CORE/extLong.h index 52ba91e321ae..c4146ebad84a 100644 --- a/CGAL_Core/include/CGAL/CORE/extLong.h +++ b/CGAL_Core/include/CGAL/CORE/extLong.h @@ -31,6 +31,9 @@ #include #include +#include +#include + namespace CORE { #ifndef LONG_MAX @@ -77,6 +80,9 @@ class CGAL_CORE_EXPORT extLong { extLong(long); /// constructor for \c unsigned long extLong(unsigned long); + /// constructor for \c std::size_t + template && !std::is_same_v>> + extLong(T s); //@} /// \name Arithmetic and assignment operators @@ -149,8 +155,7 @@ const extLong EXTLONG_EIGHT(8); // private comparison function inline int extLong::cmp(const extLong& x) const { if (isNaN() || x.isNaN()) { - core_error("Two extLong NaN's cannot be compared!", - __FILE__, __LINE__, false); + CGAL_CORE_warning_msg(false, "Two extLong NaN's cannot be compared!"); } return (val == x.val) ? 0 : ((val > x.val) ? 1 : -1); } @@ -189,6 +194,17 @@ inline extLong::extLong(unsigned long u) { } } +template +inline extLong::extLong(T u) { + if (u >= (std::numeric_limits::max)()) { + val = EXTLONG_MAX; + flag = 1; + } else { + val = static_cast(u); + flag = 0; + } +} + // isNaN defaults to false inline extLong::extLong(bool isNaN) : val(0), flag(0) { if (isNaN) { diff --git a/CGAL_Core/include/CGAL/CORE/extLong_impl.h b/CGAL_Core/include/CGAL/CORE/extLong_impl.h index 24c2bab879d4..1d636545eeee 100644 --- a/CGAL_Core/include/CGAL/CORE/extLong_impl.h +++ b/CGAL_Core/include/CGAL/CORE/extLong_impl.h @@ -77,7 +77,7 @@ extLong& extLong::operator+= (const extLong& y) { if (flag == 2 || y.flag == 2 || (flag * y.flag < 0)) { #ifdef CORE_DEBUG if (flag * y.flag < 0) //want a message at the first creation of NaN - core_error("extLong NaN Error in addition.", __FILE__, __LINE__, false); + CGAL_CORE_warning_msg(false, "extLong NaN Error in addition."); #endif *this = CORE_NaNLong; @@ -96,7 +96,7 @@ extLong& extLong::operator-= (const extLong& y) { if (flag == 2 || y.flag == 2 || (flag * y.flag > 0)) { #ifdef CORE_DEBUG if (flag * y.flag > 0) //want a message at the first creation of NaN - core_error("extLong NaN Error in subtraction.", __FILE__, __LINE__, false); + CGAL_CORE_warning_msg(false, "extLong NaN Error in subtraction."); #endif *this = CORE_NaNLong; @@ -131,7 +131,7 @@ extLong& extLong::operator*= (const extLong& y) { *this = CORE_negInfty; } else { #ifdef CORE_DEBUG - core_error("extLong NaN Error in multiplication.",__FILE__,__LINE__,false); + CGAL_CORE_warning_msg(false, "extLong NaN Error in multiplication."); #endif *this = CORE_NaNLong; } @@ -144,9 +144,9 @@ extLong& extLong::operator/= (const extLong& y) { if (flag==2 || y.flag==2 || ((flag != 0) && (y.flag != 0)) || (y.val == 0)) { #ifdef CORE_DEBUG if (y.val == 0) - core_error("extLong NaN Error, Divide by Zero.", __FILE__, __LINE__, false); + CGAL_CORE_warning_msg(false, "extLong NaN Error, Divide by Zero."); else if ((flag !=0) && (y.flag !=0)) - core_error("extLong NaN Error, +/-Inf/Inf.", __FILE__, __LINE__, false); + CGAL_CORE_warning_msg(false, "extLong NaN Error, +/-Inf/Inf."); #endif *this = CORE_NaNLong; @@ -180,8 +180,7 @@ extLong extLong::operator- () const { // you cannot interpret the returned value! CGAL_INLINE_FUNCTION int extLong::sign() const { - if (flag == 2) - core_error("NaN Sign can not be determined!", __FILE__, __LINE__, false); + CGAL_CORE_warning_msg(flag != 2, "NaN Sign can not be determined!"); return ((val == 0) ? 0 : ((val > 0) ? 1 : -1)); } diff --git a/CGAL_Core/include/CGAL/CORE/poly/Curves.tcc b/CGAL_Core/include/CGAL/CORE/poly/Curves.tcc index 4a9c8fb905c0..3f53e34da44e 100644 --- a/CGAL_Core/include/CGAL/CORE/poly/Curves.tcc +++ b/CGAL_Core/include/CGAL/CORE/poly/Curves.tcc @@ -1336,7 +1336,7 @@ cout <<"Number of roots at " << xCurr << " are " << numRoots<::pseudoRemainder :\n -- divide by zero polynomial", __FILE__, __LINE__, false); + CGAL_CORE_warning_msg(false, "ERROR in Polynomial::pseudoRemainder :\n -- divide by zero polynomial"); return Polynomial(0); // Unit Polynomial (arbitrary!) } if (bTrueDegree > degree) { @@ -771,8 +771,8 @@ BigFloat Polynomial::eval(const BigFloat& f) const { // evaluation template template -MAX_TYPE(NT, T) Polynomial::eval(const T& f) const { // evaluation - typedef MAX_TYPE(NT, T) ResultT; +CORE_MAX_TYPE(NT, T) Polynomial::eval(const T& f) const { // evaluation + typedef CORE_MAX_TYPE(NT, T) ResultT; if (degree == -1) return ResultT(0); if (degree == 0) @@ -892,10 +892,10 @@ BigFloat Polynomial::CauchyUpperBound() const { NT mx = 0; int deg = getTrueDegree(); for (int i = 0; i < deg; ++i) { - mx = core_max(mx, abs(coeff[i])); + mx = core_max(mx, NT(abs(coeff[i]))); } Expr e = mx; - e /= Expr(abs(coeff[deg])); + e /= Expr(NT(abs(coeff[deg]))); e.approx(CORE_INFTY, 2); // get an absolute approximate value with error < 1/4 return (e.BigFloatValue().makeExact() + 2); @@ -922,7 +922,7 @@ BigInt Polynomial::CauchyBound() const { /* compute B^{deg} */ if (rhs <= lhs) { B <<= 1; - rhs *= (BigInt(1)<::UpperBound() const { /* compute B^{deg} */ if (rhs <= (std::max)(lhsPos,lhsNeg)) { B <<= 1; - rhs *= (BigInt(1)<::CauchyLowerBound() const { NT mx = 0; int deg = getTrueDegree(); for (int i = 1; i <= deg; ++i) { - mx = core_max(mx, abs(coeff[i])); + mx = core_max(mx, NT(abs(coeff[i]))); } - Expr e = Expr(abs(coeff[0]))/ Expr(abs(coeff[0]) + mx); + Expr e = Expr(NT(abs(coeff[0])))/ Expr(NT(NT(abs(coeff[0])) + mx)); e.approx(2, CORE_INFTY); // get an relative approximate value with error < 1/4 return (e.BigFloatValue().makeExact().div2()); @@ -1018,8 +1018,8 @@ BigFloat Polynomial::height() const { int deg = getTrueDegree(); NT ht = 0; for (int i = 0; i< deg; i++) - if (ht < abs(coeff[i])) - ht = abs(coeff[i]); + if (ht < NT(abs(coeff[i]))) + ht = NT(abs(coeff[i])); return BigFloat(ht); } diff --git a/CGAL_Core/include/CGAL/CORE/poly/Sturm.h b/CGAL_Core/include/CGAL/CORE/poly/Sturm.h index d044b124c1f2..2fe00e3706d8 100644 --- a/CGAL_Core/include/CGAL/CORE/poly/Sturm.h +++ b/CGAL_Core/include/CGAL/CORE/poly/Sturm.h @@ -607,8 +607,7 @@ class Sturm { if (ff == 0) { NEWTON_DIV_BY_ZERO = true; del = 0; - core_error("Zero divisor in Newton Iteration", - __FILE__, __LINE__, false); + CGAL_CORE_warning_msg(false, "Zero divisor in Newton Iteration"); return 0; } @@ -680,8 +679,7 @@ class Sturm { stepsize++; // heuristic } while ((del != 0) && ((del.uMSB() >= -prec) && (count >0))) ; - if (count == 0) core_error("newtonIterE: reached count=0", - __FILE__, __LINE__, true); + CGAL_assertion_msg(count != 0, "newtonIterE: reached count=0"); del = BigFloat(core_abs(del.m()), err, del.exp() ); del.makeCeilExact(); return val; diff --git a/CGAL_Core/package_info/CGAL_Core/license.txt b/CGAL_Core/package_info/CGAL_Core/license.txt index 66d68590d248..5c1c5d8436f8 100644 --- a/CGAL_Core/package_info/CGAL_Core/license.txt +++ b/CGAL_Core/package_info/CGAL_Core/license.txt @@ -1,2 +1 @@ -LGPL (v3) LGPL (v3 or later) diff --git a/Circular_kernel_2/package_info/Circular_kernel_2/dependencies b/Circular_kernel_2/package_info/Circular_kernel_2/dependencies index ffbd888bc135..2621ba85ea7c 100644 --- a/Circular_kernel_2/package_info/Circular_kernel_2/dependencies +++ b/Circular_kernel_2/package_info/Circular_kernel_2/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Algebraic_kernel_for_circles Arithmetic_kernel +CGAL_Core Cartesian_kernel Circular_kernel_2 Distance_2 diff --git a/Circular_kernel_3/package_info/Circular_kernel_3/dependencies b/Circular_kernel_3/package_info/Circular_kernel_3/dependencies index dfceb904b448..476a5513bf01 100644 --- a/Circular_kernel_3/package_info/Circular_kernel_3/dependencies +++ b/Circular_kernel_3/package_info/Circular_kernel_3/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Algebraic_kernel_for_spheres Arithmetic_kernel +CGAL_Core Cartesian_kernel Circular_kernel_3 Distance_2 diff --git a/Combinatorial_map/package_info/Combinatorial_map/dependencies b/Combinatorial_map/package_info/Combinatorial_map/dependencies index 279a01a72ae2..0902e1798f1a 100644 --- a/Combinatorial_map/package_info/Combinatorial_map/dependencies +++ b/Combinatorial_map/package_info/Combinatorial_map/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Arithmetic_kernel BGL +CGAL_Core Cartesian_kernel Circulator Combinatorial_map diff --git a/Convex_decomposition_3/package_info/Convex_decomposition_3/dependencies b/Convex_decomposition_3/package_info/Convex_decomposition_3/dependencies index fa1556add87e..09382985c877 100644 --- a/Convex_decomposition_3/package_info/Convex_decomposition_3/dependencies +++ b/Convex_decomposition_3/package_info/Convex_decomposition_3/dependencies @@ -2,6 +2,7 @@ Algebraic_foundations Arithmetic_kernel BGL Box_intersection_d +CGAL_Core Cartesian_kernel Circulator Convex_decomposition_3 diff --git a/Convex_hull_3/package_info/Convex_hull_3/dependencies b/Convex_hull_3/package_info/Convex_hull_3/dependencies index 406722ba9aff..bdd3aa15916c 100644 --- a/Convex_hull_3/package_info/Convex_hull_3/dependencies +++ b/Convex_hull_3/package_info/Convex_hull_3/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Arithmetic_kernel BGL +CGAL_Core Cartesian_kernel Circulator Convex_hull_2 diff --git a/Documentation/doc/Documentation/Third_party.txt b/Documentation/doc/Documentation/Third_party.txt index b50e062d61ce..ceb3eb7e74a9 100644 --- a/Documentation/doc/Documentation/Third_party.txt +++ b/Documentation/doc/Documentation/Third_party.txt @@ -56,7 +56,7 @@ or `h The \stl comes with the compiler, and as such no installation is required. \subsection thirdpartyBoost Boost -Version 1.66 or later +Version 1.72 or later The \boost libraries are a set of portable C++ source libraries. Most of \boost libraries are header-only, but a few of them need to be compiled or @@ -72,7 +72,7 @@ from `htt As there is no canonical directory for where to find \boost on Windows, we recommend that you define the environment variable -`BOOST_ROOT` and set it to where you have installed \boost, e.g., `C:\boost\boost_1_69_0`. +`BOOST_ROOT` and set it to where you have installed \boost, e.g., `C:\boost\boost_1_70_0`. \subsection thirdpartyMPFR GNU Multiple Precision Arithmetic (GMP) and GNU Multiple Precision Floating-Point Reliably (MPFR) Libraries GMP Version 4.2 or later, MPFR Version 2.2.1 or later diff --git a/Documentation/doc/Documentation/advanced/Configuration_variables.txt b/Documentation/doc/Documentation/advanced/Configuration_variables.txt index 7c475f547766..d4ac891a30f5 100644 --- a/Documentation/doc/Documentation/advanced/Configuration_variables.txt +++ b/Documentation/doc/Documentation/advanced/Configuration_variables.txt @@ -103,8 +103,8 @@ other but never both. \subsection installation_boost Boost Libraries -\subsubsection inst_boost_1_70_plus Version 1.70 and Later -Starting from \boost 1.70, the cmake config mode can be used for configuring the \boost version +\subsubsection inst_boost_1_72_plus Version 1.72 and Later +Starting from \boost 1.72, the cmake config mode can be used for configuring the \boost version to use by setting the environment variable `Boost_DIR` to the path containing the file `BoostConfig.cmake`. For example if you manually installed \boost 1.77 with `--prefix=`, then you should set `Boost_DIR=/lib/cmake/Boost-1.77.0`. diff --git a/Envelope_3/include/CGAL/Env_sphere_traits_3.h b/Envelope_3/include/CGAL/Env_sphere_traits_3.h index 3d272f81b29f..bb7f34a25be0 100644 --- a/Envelope_3/include/CGAL/Env_sphere_traits_3.h +++ b/Envelope_3/include/CGAL/Env_sphere_traits_3.h @@ -265,7 +265,7 @@ class Env_sphere_traits_3 : public ConicTraits_2 { if (n_ys == 0) return o; // no intersection // the x coordinate of the solution points - Algebraic xs = m / (2*a_diff); + Algebraic xs = m / (Rational(2)*a_diff); if (n_ys == 1) { // intersection is a point @@ -340,7 +340,7 @@ class Env_sphere_traits_3 : public ConicTraits_2 { } if (n_xs == 1) { // intersection is a point - Point_2 inter_point(xs[0], (-2*a_diff*xs[0] + m)/(2*b_diff) ); + Point_2 inter_point(xs[0], (-Rational(2)*a_diff*xs[0] + m)/(Rational(2)*b_diff) ); *o++ = inter_point; return o; } @@ -350,8 +350,8 @@ class Env_sphere_traits_3 : public ConicTraits_2 { // so we construct a COLLINEAR conic (with equation as in (1)) // with 2 endpoints Algebraic ys[2]; - ys[0] = (-2*a_diff*xs[0] + m)/(2*b_diff); - ys[1] = (-2*a_diff*xs[1] + m)/(2*b_diff); + ys[0] = (-Rational(2)*a_diff*xs[0] + m)/(Rational(2)*b_diff); + ys[1] = (-Rational(2)*a_diff*xs[1] + m)/(Rational(2)*b_diff); Alg_point_2 end1(xs[0], ys[0]); Alg_point_2 end2(xs[1], ys[1]); @@ -457,7 +457,7 @@ class Env_sphere_traits_3 : public ConicTraits_2 { int envelope_coef = 1; if (! m_traits.m_is_lower) envelope_coef = -1; - Sign sign_c_diff = CGAL_NTS sign(c_diff); + Rational sign_c_diff = Rational(sign(c_diff)); Rational la = envelope_coef*2*a_diff*sign_c_diff; Rational lb = envelope_coef*2*b_diff*sign_c_diff; Rational lc = envelope_coef*sign_c_diff*(2*c_diff*z_plane - m); @@ -977,10 +977,10 @@ class Env_sphere_traits_3 : public ConicTraits_2 { const Rational& u = cv.u(); const Rational& v = cv.v(); // const Rational& w = cv.w(); // unused - Algebraic m = -1 * (2*r*x0 + t*y0 + u); - Algebraic n = 2*s*y0 + t*x0 + v; + Algebraic m = -1 * (Rational(2)*r*x0 + t*y0 + u); + Algebraic n = Rational(2)*s*y0 + t*x0 + v; // line coefficients: A3, B3, C3 - Algebraic A3 = -1*m, B3 = n, C3 = m*x0 - n*y0; + Algebraic A3 = -m, B3 = n, C3 = m*x0 - n*y0; // the tangences of the spheres (in point (x0,y0,z0)): Algebraic z0 = compute_envelope_z_in_point(cv_point, s1); @@ -1077,8 +1077,8 @@ class Env_sphere_traits_3 : public ConicTraits_2 { Algebraic x_diff = x1 - a, y_diff = y1 - b; // the coefficients are: Algebraic A = 1; - Algebraic B = -2*c; - Algebraic C = x_diff*x_diff + y_diff*y_diff + c*c - sqr_r; + Algebraic B = -Rational(2)*c; + Algebraic C = x_diff*x_diff + y_diff*y_diff + Algebraic(c*c - sqr_r); Algebraic zs[2]; Algebraic* zs_end; diff --git a/Envelope_3/package_info/Envelope_3/dependencies b/Envelope_3/package_info/Envelope_3/dependencies index 5abc02d0186e..8b0ee9f9511a 100644 --- a/Envelope_3/package_info/Envelope_3/dependencies +++ b/Envelope_3/package_info/Envelope_3/dependencies @@ -2,6 +2,7 @@ Algebraic_foundations Apollonius_graph_2 Arithmetic_kernel Arrangement_on_surface_2 +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Filtered_kernel/package_info/Filtered_kernel/dependencies b/Filtered_kernel/package_info/Filtered_kernel/dependencies index 4b009ce54e47..5e320e639525 100644 --- a/Filtered_kernel/package_info/Filtered_kernel/dependencies +++ b/Filtered_kernel/package_info/Filtered_kernel/dependencies @@ -1,5 +1,6 @@ Algebraic_foundations Arithmetic_kernel +CGAL_Core Cartesian_kernel Distance_2 Distance_3 diff --git a/Generalized_map/package_info/Generalized_map/dependencies b/Generalized_map/package_info/Generalized_map/dependencies index bf19ede8a16d..97e368892d5e 100644 --- a/Generalized_map/package_info/Generalized_map/dependencies +++ b/Generalized_map/package_info/Generalized_map/dependencies @@ -1,5 +1,6 @@ Algebraic_foundations Arithmetic_kernel +CGAL_Core Cartesian_kernel Circulator Combinatorial_map diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index 79678badc697..906bd670cf89 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -15,6 +15,11 @@ Release date: October 2023 - **Breaking change**: The usage of `boost::optional` has been replaced by `std::optional`. Packages affected are 2D Straight Line Skeleton, 3D Fast Intersection and Distance Computation (AABB Tree), and the Kernel intersection. - **Breaking change**: The usage of `boost::variant` has been replaced by `std::variant`. Packages affected are 2D Arrangements, and the Kernel intersection. - **Breaking change**: The file CMake file `UseCGAL.cmake` has been removed from CGAL. Usages of the CMake variables `${CGAL_USE_FILE}` and `${CGAL_LIBRARIES}` must be replaced by a link to the imported target `CGAL::CGAL`, for example: `target_link_library(the_target PRIVATE CGAL::CGAL)`. +- The minimal supported version of Boost is now 1.72.0 + +### Installation + +- The CGAL\_Core library is no longer based on GMP but boost multiprecision now, and can be used with either gmp backend or boost backend. ### [Polygon Repair](https://doc.cgal.org/6.0/Manual/packages.html#PkgPolygonRepair) (new package) diff --git a/Installation/CMakeLists.txt b/Installation/CMakeLists.txt index fa2102ff7c00..6335ead84111 100644 --- a/Installation/CMakeLists.txt +++ b/Installation/CMakeLists.txt @@ -115,6 +115,9 @@ option(CGAL_ENABLE_TESTING "Build the testing tree." ${BUILD_TESTING}) endif() endif(CGAL_BRANCH_BUILD) +#allow to force disabling boost multiprecision support +option(CGAL_DO_NOT_USE_BOOST_MP "Disable the support of boost multiprecision library" FALSE) + #message(STATUS "Packages found: ${CGAL_CONFIGURED_PACKAGES}") list(SORT CGAL_CONFIGURED_PACKAGES_NAMES) diff --git a/Installation/cmake/modules/CGAL_SetupBoost.cmake b/Installation/cmake/modules/CGAL_SetupBoost.cmake index fccdd488a68f..ee561027370d 100644 --- a/Installation/cmake/modules/CGAL_SetupBoost.cmake +++ b/Installation/cmake/modules/CGAL_SetupBoost.cmake @@ -17,9 +17,9 @@ set ( CGAL_Boost_Setup TRUE ) include(${CMAKE_CURRENT_LIST_DIR}/CGAL_TweakFindBoost.cmake) -find_package( Boost 1.66 REQUIRED ) +find_package( Boost 1.72 REQUIRED ) -if(Boost_FOUND AND Boost_VERSION VERSION_LESS 1.70) +if(Boost_FOUND AND Boost_VERSION VERSION_LESS 1.72) if(DEFINED Boost_DIR AND NOT Boost_DIR) # Unset that cache variable that is set in the cache by FindBoost # (while it was searching for boost-cmake). diff --git a/Installation/cmake/modules/CGAL_SetupCGALDependencies.cmake b/Installation/cmake/modules/CGAL_SetupCGALDependencies.cmake index 1d51bbbdac5f..347ab99e71c0 100644 --- a/Installation/cmake/modules/CGAL_SetupCGALDependencies.cmake +++ b/Installation/cmake/modules/CGAL_SetupCGALDependencies.cmake @@ -131,12 +131,6 @@ function(CGAL_setup_CGAL_flags target) $<$:/fp:except-> $<$:/bigobj> # Use /bigobj by default ) - elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "AppleClang") - if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 11.0.3) - message(STATUS "Apple Clang version ${CMAKE_CXX_COMPILER_VERSION} compiler detected") - message(STATUS "Boost MP is turned off for all Apple Clang versions below 11.0.3!") - target_compile_options(${target} INTERFACE "-DCGAL_DO_NOT_USE_BOOST_MP") - endif() elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel") message( STATUS "Using Intel Compiler. Adding -fp-model strict" ) if(WIN32) @@ -166,4 +160,9 @@ function(CGAL_setup_CGAL_flags target) target_compile_options(${target} INTERFACE "-mieee" "-mfp-rounding-mode=d" ) endif() endif() + + if (CGAL_DO_NOT_USE_BOOST_MP) + target_compile_options(${target} INTERFACE "-DCGAL_DO_NOT_USE_BOOST_MP") + endif() + endfunction() diff --git a/Installation/cmake/modules/CGAL_SetupCGAL_CoreDependencies.cmake b/Installation/cmake/modules/CGAL_SetupCGAL_CoreDependencies.cmake index 88b5db13449a..816ae656fb43 100644 --- a/Installation/cmake/modules/CGAL_SetupCGAL_CoreDependencies.cmake +++ b/Installation/cmake/modules/CGAL_SetupCGAL_CoreDependencies.cmake @@ -18,9 +18,6 @@ endif() set(CGAL_SetupCGAL_CoreDependencies_included TRUE) #.rst: -# Used Modules -# ^^^^^^^^^^^^ -# - :module:`CGAL_SetupGMP` # # Result Variables # ^^^^^^^^^^^^^^^^ @@ -29,13 +26,10 @@ set(CGAL_SetupCGAL_CoreDependencies_included TRUE) # # Set to `TRUE` if the dependencies of `CGAL_Core` were found. -if(NOT CGAL_DISABLE_GMP) - include(${CMAKE_CURRENT_LIST_DIR}/CGAL_SetupGMP.cmake) - if(GMP_FOUND) - set(CGAL_Core_FOUND TRUE) - set_property(GLOBAL PROPERTY CGAL_Core_FOUND TRUE) - endif() -endif() + +# always found as it requires the minimal version of boost required by CGAL +set(CGAL_Core_FOUND TRUE) +set_property(GLOBAL PROPERTY CGAL_Core_FOUND TRUE) #.rst: # @@ -54,8 +48,10 @@ endif() # function(CGAL_setup_CGAL_Core_dependencies target) - use_CGAL_GMP_support(CGAL_Core INTERFACE) + find_package( Boost 1.72 REQUIRED ) + if (!CGAL_DISABLE_GMP AND GMP_FOUND) + use_CGAL_GMP_support(CGAL_Core INTERFACE) + endif() target_compile_definitions(${target} INTERFACE CGAL_USE_CORE=1) target_link_libraries( CGAL_Core INTERFACE CGAL::CGAL ) - endfunction() diff --git a/Installation/cmake/modules/CGAL_SetupDependencies.cmake b/Installation/cmake/modules/CGAL_SetupDependencies.cmake deleted file mode 100644 index 6051c7d3ce47..000000000000 --- a/Installation/cmake/modules/CGAL_SetupDependencies.cmake +++ /dev/null @@ -1,13 +0,0 @@ -include(${CMAKE_CURRENT_LIST_DIR}/CGAL_Macros.cmake) - -if( (GMP_FOUND AND NOT MPFR_FOUND) OR (NOT GMP_FOUND AND MPFR_FOUND) ) - message( FATAL_ERROR "CGAL needs for its full functionality both GMP and MPFR.") -endif() - -if( NOT GMP_FOUND ) - set(CGAL_NO_CORE ON) - message( STATUS "CGAL_Core needs GMP, cannot be configured.") -endif( NOT GMP_FOUND ) - -# finally setup Boost -include(${CMAKE_CURRENT_LIST_DIR}/CGAL_SetupBoost.cmake) diff --git a/Installation/include/CGAL/Installation/internal/enable_third_party_libraries.h b/Installation/include/CGAL/Installation/internal/enable_third_party_libraries.h index dd9ecf8c7070..461a41707d11 100644 --- a/Installation/include/CGAL/Installation/internal/enable_third_party_libraries.h +++ b/Installation/include/CGAL/Installation/internal/enable_third_party_libraries.h @@ -35,8 +35,32 @@ # endif // CGAL_USE_MPFR and no #endif // __has_include -#if CGAL_USE_GMP && CGAL_USE_MPFR && ! CGAL_NO_CORE + +// It is easier to disable this number type completely for old versions. +// Before 1.63, I/O is broken. Again, disabling the whole file is just the +// easy solution. +// MSVC had trouble with versions <= 1.69: +// https://github.com/boostorg/multiprecision/issues/98 +// +// Disable also on Windows 32 bits +// because CGAL/cpp_float.h assumes _BitScanForward64 is available +// See https://learn.microsoft.com/en-us/cpp/intrinsics/bitscanforward-bitscanforward64 +// +// Disable also with PowerPC processors, with Boost<1.80 because of that bug: +// https://github.com/boostorg/multiprecision/pull/421 +// +#if !defined CGAL_DO_NOT_USE_BOOST_MP && \ + (!defined _MSC_VER || BOOST_VERSION >= 107000) && \ + (!defined _WIN32 || defined _WIN64) && \ + (BOOST_VERSION >= 108000 || (!defined _ARCH_PPC && !defined _ARCH_PPC64)) +#define CGAL_USE_BOOST_MP 1 +#endif + + +#if CGAL_USE_BOOST_MP +#if ! CGAL_NO_CORE # define CGAL_USE_CORE 1 #endif +#endif #endif // CGAL_INTERNAL_ENABLE_THIRD_PARTY_LIBRARIES_H diff --git a/Installation/lib/cmake/CGAL/CGALConfig.cmake b/Installation/lib/cmake/CGAL/CGALConfig.cmake index 93e9e8830f0a..0ebd009ac8d8 100644 --- a/Installation/lib/cmake/CGAL/CGALConfig.cmake +++ b/Installation/lib/cmake/CGAL/CGALConfig.cmake @@ -127,12 +127,18 @@ if( CGAL_DEV_MODE OR RUNNING_CGAL_AUTO_TEST OR CGAL_TEST_SUITE ) endif() endif() +if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "AppleClang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 11.0.3) + message(STATUS "Apple Clang version ${CMAKE_CXX_COMPILER_VERSION} compiler detected") + message(STATUS "Boost MP is turned off for all Apple Clang versions below 11.0.3!") + set(CGAL_DO_NOT_USE_BOOST_MP TRUE) +endif() + foreach(comp ${CGAL_FIND_COMPONENTS}) if(NOT comp MATCHES "Core|ImageIO|Qt6") message(FATAL_ERROR "The requested CGAL component ${comp} does not exist!") endif() - if(comp MATCHES "Core" AND CGAL_DISABLE_GMP) - message("CGAL_Core needs GMP and won't be used.") + if(comp MATCHES "Core" AND CGAL_DO_NOT_USE_BOOST_MP) + message(STATUS "CGAL_Core needs Boost multiprecision support and won't be used.") else() list(APPEND CGAL_LIBRARIES CGAL_${comp}) endif() diff --git a/LICENSES/LGPL-3.0-only.txt b/LICENSES/LGPL-3.0-only.txt deleted file mode 100644 index 65c5ca88a67c..000000000000 --- a/LICENSES/LGPL-3.0-only.txt +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/Linear_cell_complex/package_info/Linear_cell_complex/dependencies b/Linear_cell_complex/package_info/Linear_cell_complex/dependencies index 53e5ce3f1530..a3ecaf39ee28 100644 --- a/Linear_cell_complex/package_info/Linear_cell_complex/dependencies +++ b/Linear_cell_complex/package_info/Linear_cell_complex/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Arithmetic_kernel BGL +CGAL_Core Cartesian_kernel Circulator Combinatorial_map diff --git a/Mesh_3/package_info/Mesh_3/dependencies b/Mesh_3/package_info/Mesh_3/dependencies index 65eec56b3606..0f9c65cd105b 100644 --- a/Mesh_3/package_info/Mesh_3/dependencies +++ b/Mesh_3/package_info/Mesh_3/dependencies @@ -2,6 +2,7 @@ AABB_tree Algebraic_foundations Arithmetic_kernel BGL +CGAL_Core CGAL_ImageIO Cartesian_kernel Circulator diff --git a/Minkowski_sum_2/package_info/Minkowski_sum_2/dependencies b/Minkowski_sum_2/package_info/Minkowski_sum_2/dependencies index 62f64c4bfd1c..a71a4c66f559 100644 --- a/Minkowski_sum_2/package_info/Minkowski_sum_2/dependencies +++ b/Minkowski_sum_2/package_info/Minkowski_sum_2/dependencies @@ -3,6 +3,7 @@ Algebraic_foundations Arithmetic_kernel Arrangement_on_surface_2 Boolean_set_operations_2 +CGAL_Core Cartesian_kernel Circulator Convex_hull_2 diff --git a/Minkowski_sum_3/package_info/Minkowski_sum_3/dependencies b/Minkowski_sum_3/package_info/Minkowski_sum_3/dependencies index e2123abc9c96..b60f37e8338f 100644 --- a/Minkowski_sum_3/package_info/Minkowski_sum_3/dependencies +++ b/Minkowski_sum_3/package_info/Minkowski_sum_3/dependencies @@ -2,6 +2,7 @@ Algebraic_foundations Arithmetic_kernel BGL Box_intersection_d +CGAL_Core Cartesian_kernel Circulator Convex_decomposition_3 diff --git a/Nef_3/package_info/Nef_3/dependencies b/Nef_3/package_info/Nef_3/dependencies index 7fec88e23734..92337ba55f10 100644 --- a/Nef_3/package_info/Nef_3/dependencies +++ b/Nef_3/package_info/Nef_3/dependencies @@ -2,6 +2,7 @@ Algebraic_foundations Arithmetic_kernel BGL Box_intersection_d +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/NewKernel_d/package_info/NewKernel_d/dependencies b/NewKernel_d/package_info/NewKernel_d/dependencies index 04e1d32ff873..bfb2e6e60407 100644 --- a/NewKernel_d/package_info/NewKernel_d/dependencies +++ b/NewKernel_d/package_info/NewKernel_d/dependencies @@ -1,5 +1,6 @@ Algebraic_foundations Arithmetic_kernel +CGAL_Core Filtered_kernel Installation Interval_support diff --git a/Number_types/include/CGAL/CORE_BigFloat.h b/Number_types/include/CGAL/CORE_BigFloat.h index 812036e3aa60..e2def9175fb3 100644 --- a/Number_types/include/CGAL/CORE_BigFloat.h +++ b/Number_types/include/CGAL/CORE_BigFloat.h @@ -178,13 +178,16 @@ class Interval_traits // shift such that err.m()+err.err() fits into long int digits_long = std::numeric_limits::digits; - if(::CORE::bitLength(err.m()+err.err()) >= digits_long){ - long shift = ::CORE::bitLength(err.m()) - digits_long + 1 ; + if(::CORE::bitLength(err.m()+err.err()) >= static_cast(digits_long)){ + assert(std::size_t((std::numeric_limits::max)()) > ::CORE::bitLength(err.m())); + long shift = static_cast(::CORE::bitLength(err.m())) - digits_long + 1; //std::cout << "shift " << shift<< std::endl; - long new_err = ((err.m()+err.err()) >> shift).longValue()+1; + CORE::BigInt bi = (err.m() + err.err()); + bi = bi >> shift; + long new_err = CORE::longValue(bi)+1; err = CORE::BigFloat(0,new_err,0) * CORE::BigFloat::exp2(err.exp()*CORE::CHUNK_BIT+shift); }else{ - err = CORE::BigFloat(0,err.m().longValue()+err.err(),err.exp()); + err = CORE::BigFloat(0, CORE::longValue(err.m())+err.err(),err.exp()); } //print_bf(err,"new_err"); @@ -272,9 +275,10 @@ round(const CORE::BigFloat& x, long rel_prec = CORE::get_static_defRelPrec().toL // long shift = ::CORE::bitLength(m) - rel_prec - 1; long shift ; - if (err == 0) - shift = ::CORE::bitLength(m) - rel_prec - 3; - else + if (err == 0) { + assert(std::size_t((std::numeric_limits::max)()) > ::CORE::bitLength(m)); + shift = static_cast(::CORE::bitLength(m)) - rel_prec - 3; + }else shift = CGAL::relative_precision(x) - rel_prec -1; if( shift > 0 ){ @@ -324,7 +328,7 @@ template<> class Bigfloat_interval_traits NT w = Width()(x); w /= ::CORE::BigFloat(x.m()-x.err(),0,x.exp()); w = w.abs(); - return -(CORE::ceilLg(w.m()+w.err())+w.exp()*CORE::CHUNK_BIT); + return -(CORE::ceilLg(CORE::BigInt(w.m()+w.err()))+w.exp()*CORE::CHUNK_BIT); } }; diff --git a/Number_types/include/CGAL/CORE_BigInt.h b/Number_types/include/CGAL/CORE_BigInt.h index 0b599543164a..d9be3a695d21 100644 --- a/Number_types/include/CGAL/CORE_BigInt.h +++ b/Number_types/include/CGAL/CORE_BigInt.h @@ -10,7 +10,6 @@ // // Author(s) : Michael Hemmer - #ifndef CGAL_CORE_BIGINT_H #define CGAL_CORE_BIGINT_H @@ -24,198 +23,6 @@ #include #include -namespace CGAL { - -// -// Algebraic structure traits -// -template <> class Algebraic_structure_traits< CORE::BigInt > - : public Algebraic_structure_traits_base< CORE::BigInt, - Euclidean_ring_tag > { - public: - typedef Tag_true Is_exact; - typedef Tag_false Is_numerical_sensitive; - - typedef INTERN_AST::Is_square_per_sqrt< Type > - Is_square; - - typedef INTERN_AST::Div_per_operator< Type > Div; - typedef INTERN_AST::Mod_per_operator< Type > Mod; - - class Sqrt - : public CGAL::cpp98::unary_function< Type, Type > { - public: - //! computes the largest NT not larger than the square root of \a a. - Type operator()( const Type& x) const { - Type result; - mpz_sqrt(result.get_mp(), x.get_mp()); - return result; - } - }; - - - class Gcd - : public CGAL::cpp98::binary_function< Type, Type, - Type > { - public: - Type operator()( const Type& x, - const Type& y) const { - if ( x == Type(0) && y == Type(0) ) - return Type(0); - Type result; - mpz_gcd(result.get_mp(), x.get_mp(), y.get_mp()); - return result; - } - }; -}; - -// -// Real embeddable traits -// -template <> class Real_embeddable_traits< CORE::BigInt > - : public INTERN_RET::Real_embeddable_traits_base< CORE::BigInt , CGAL::Tag_true > { - - public: - - class Abs - : public CGAL::cpp98::unary_function< Type, Type > { - public: - Type operator()( const Type& x ) const { - return CORE::abs( x ); - } - }; - - class Sgn - : public CGAL::cpp98::unary_function< Type, ::CGAL::Sign > { - public: - ::CGAL::Sign operator()( const Type& x ) const { - return (::CGAL::Sign) CORE::sign( x ); - } - }; - - class Compare - : public CGAL::cpp98::binary_function< Type, Type, - Comparison_result > { - public: - Comparison_result operator()( const Type& x, - const Type& y ) const { - return CGAL::sign(::CORE::cmp(x,y)); - } - }; - - class To_double - : public CGAL::cpp98::unary_function< Type, double > { - public: - double operator()( const Type& x ) const { - // this call is required to get reasonable values for the double - // approximation - return x.doubleValue(); - } - }; - - class To_interval - : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { - public: - std::pair operator()( const Type& x_ ) const { - CORE::Expr x(x_); - std::pair result; - x.doubleInterval(result.first, result.second); - CGAL_expensive_assertion(result.first <= x); - CGAL_expensive_assertion(result.second >= x); - return result; - } - }; -}; - -/*! \ingroup NiX_Modular_traits_spec - * \brief a model of concept ModularTraits, - * specialization of NiX::Modular_traits. - */ -template<> -class Modular_traits< ::CORE::BigInt > { - typedef Residue RES; - public: - typedef ::CORE::BigInt NT; - typedef CGAL::Tag_true Is_modularizable; - typedef Residue Residue_type; - - struct Modular_image{ - Residue_type operator()(const NT& a){ - NT tmp = a % NT(RES::get_current_prime()); -// TODO: reactivate this assertion -// it fails with core_v1.6x_20040329 -// NiX_assert(tmp.isInt()); - int mi(tmp.longValue()); - if (mi < 0) mi += RES::get_current_prime(); - return Residue_type(mi); - } - }; - struct Modular_image_representative{ - NT operator()(const Residue_type& x){ - return NT(x.get_value()); - } - }; -}; - - -template<> -struct Needs_parens_as_product{ - bool operator()(const CORE::BigInt& x){ - return CGAL_NTS is_negative(x); - } -}; - -// Benchmark_rep specialization -template<> -class Benchmark_rep< CORE::BigInt > { - const CORE::BigInt& t; -public: - //! initialize with a const reference to \a t. - Benchmark_rep( const CORE::BigInt& tt) : t(tt) {} - //! perform the output, calls \c operator\<\< by default. - std::ostream& operator()( std::ostream& out) const { - out << t; - return out; - } - - static std::string get_benchmark_name() { - return "Integer"; - } -}; - - -} //namespace CGAL - -//since types are included by CORE_coercion_traits.h: -#include -#include -#include -#include - -namespace Eigen { - template struct NumTraits; - template<> struct NumTraits - { - typedef CORE::BigInt Real; - typedef CORE::BigRat NonInteger; - typedef CORE::BigInt Nested; - typedef CORE::BigInt Literal; - - static inline Real epsilon() { return 0; } - static inline Real dummy_precision() { return 0; } - - enum { - IsInteger = 1, - IsSigned = 1, - IsComplex = 0, - RequireInitialization = 1, - ReadCost = 6, - AddCost = 30, - MulCost = 50 - }; - }; -} - #include #endif // CGAL_CORE_BIGINT_H diff --git a/Number_types/include/CGAL/CORE_BigRat.h b/Number_types/include/CGAL/CORE_BigRat.h index caf9b73886ed..48d8e950db23 100644 --- a/Number_types/include/CGAL/CORE_BigRat.h +++ b/Number_types/include/CGAL/CORE_BigRat.h @@ -10,7 +10,6 @@ // // Author(s) : Michael Hemmer - #ifndef CGAL_CORE_BIGRAT_H #define CGAL_CORE_BIGRAT_H @@ -21,237 +20,6 @@ #include #include // used for To_interval-functor -//#if defined(CGAL_CORE_BIGRAT_NUMER_DENOM_ARE_MEMBERS) -// #define CGAL_CORE_NUMERATOR(X) ((X).numerator()) -// #define CGAL_CORE_DENOMINATOR(X) ((X).denominator()) -//#elif defined(CGAL_CORE_BIGRAT_NUMER_DENOM_ARE_NONMEMBERS) - #define CGAL_CORE_NUMERATOR(X) (numerator((X))) - #define CGAL_CORE_DENOMINATOR(X) (denominator((X))) -//#else - -namespace CGAL { - -// -// Algebraic structure traits -// -template <> class Algebraic_structure_traits< CORE::BigRat > - : public Algebraic_structure_traits_base< CORE::BigRat, - Field_tag > { - public: - typedef Tag_true Is_exact; - typedef Tag_false Is_numerical_sensitive; - - // BigRat are always normalized, so no special simplify-functor is needed - - // Nothing new... -}; - - - - -// -// Real embeddable traits -// -template <> class Real_embeddable_traits< CORE::BigRat > - : public INTERN_RET::Real_embeddable_traits_base< CORE::BigRat , CGAL::Tag_true > { - public: - - class Abs - : public CGAL::cpp98::unary_function< Type, Type > { - public: - Type operator()( const Type& x ) const { - return CORE::abs( x ); - } - }; - - class Sgn - : public CGAL::cpp98::unary_function< Type, ::CGAL::Sign > { - public: - ::CGAL::Sign operator()( const Type& x ) const { - return (::CGAL::Sign) CORE::sign( x ); - } - }; - - class Compare - : public CGAL::cpp98::binary_function< Type, Type, - Comparison_result > { - public: - Comparison_result operator()( const Type& x, - const Type& y ) const { - return CGAL::sign( ::CORE::cmp(x,y)); - } - CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR_WITH_RT(Type,Comparison_result) - }; - - class To_double - : public CGAL::cpp98::unary_function< Type, double > { - public: - double operator()( const Type& x ) const { - // this call is required to get reasonable values for the double - // approximation - return x.doubleValue(); - } - }; - - class To_interval - : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { - public: - std::pair operator()( const Type& x_ ) const { - CORE::Expr x(x_); - std::pair result; - x.doubleInterval(result.first, result.second); - CGAL_expensive_assertion(result.first <= x); - CGAL_expensive_assertion(result.second >= x); - return result; - } - }; -}; - -/*! \ingroup NiX_Fraction_traits_spec - * \brief Specialization of Fraction_traits for ::leda::rational - */ -template <> -class Fraction_traits< CORE::BigRat > { -public: - typedef CORE::BigRat Type; - typedef ::CGAL::Tag_true Is_fraction; - typedef CORE::BigInt Numerator_type; - typedef Numerator_type Denominator_type; - - typedef Algebraic_structure_traits< Numerator_type >::Gcd Common_factor; - - class Decompose { - public: - typedef Type first_argument_type; - typedef Numerator_type& second_argument_type; - typedef Numerator_type& third_argument_type; - void operator () ( - const Type& rat, - Numerator_type& num, - Numerator_type& den) { - num = CGAL_CORE_NUMERATOR(rat); - den = CGAL_CORE_DENOMINATOR(rat); - } - }; - - class Compose { - public: - typedef Numerator_type first_argument_type; - typedef Numerator_type second_argument_type; - typedef Type result_type; - Type operator ()( - const Numerator_type& num , - const Numerator_type& den ) { - return Type(num, den); - } - }; -}; - -template -class Output_rep< ::CORE::BigRat, F> : public IO_rep_is_specialized { - const ::CORE::BigRat& t; -public: - //! initialize with a const reference to \a t. - Output_rep( const ::CORE::BigRat& tt) : t(tt) {} - //! perform the output, calls \c operator\<\< by default. - std::ostream& operator()( std::ostream& out) const { - switch (IO::get_mode(out)) { - case IO::PRETTY:{ - if(CGAL_CORE_DENOMINATOR(t) == ::CORE::BigRat(1)) - return out < -struct Needs_parens_as_product< ::CORE::BigRat >{ - bool operator()( ::CORE::BigRat t){ - if (CGAL_CORE_DENOMINATOR(t) != 1 ) - return true; - else - return needs_parens_as_product(CGAL_CORE_NUMERATOR(t)) ; - } -}; - -template <> -class Output_rep< ::CORE::BigRat, Parens_as_product_tag > - : public IO_rep_is_specialized -{ - const ::CORE::BigRat& t; -public: - // Constructor - Output_rep( const ::CORE::BigRat& tt) : t(tt) {} - // operator - std::ostream& operator()( std::ostream& out) const { - Needs_parens_as_product< ::CORE::BigRat > needs_parens_as_product; - if (needs_parens_as_product(t)) - return out <<"("<< IO::oformat(t) <<")"; - else - return out << IO::oformat(t); - } -}; - -// Benchmark_rep specialization -template<> -class Benchmark_rep< CORE::BigRat > { - const CORE::BigRat& t; -public: - //! initialize with a const reference to \a t. - Benchmark_rep( const CORE::BigRat& tt) : t(tt) {} - //! perform the output, calls \c operator\<\< by default. - std::ostream& operator()( std::ostream& out) const { - out << "Rational(" << numerator(t) << "," << denominator(t) << ")"; - return out; - } - - static std::string get_benchmark_name() { - return "Rational"; - } -}; - -} //namespace CGAL - -//since types are included by CORE_coercion_traits.h: -#include -#include -#include -#include - -namespace Eigen { - template struct NumTraits; - template<> struct NumTraits - { - typedef CORE::BigRat Real; - typedef CORE::BigRat NonInteger; - typedef CORE::BigRat Nested; - typedef CORE::BigRat Literal; - - static inline Real epsilon() { return 0; } - static inline Real dummy_precision() { return 0; } - - enum { - IsInteger = 0, - IsSigned = 1, - IsComplex = 0, - RequireInitialization = 1, - ReadCost = 6, - AddCost = 150, - MulCost = 100 - }; - }; -} - #include #endif // CGAL_CORE_BIGRAT_H diff --git a/Number_types/include/CGAL/CORE_coercion_traits.h b/Number_types/include/CGAL/CORE_coercion_traits.h index cf1df0bab3eb..f5426e10cb3f 100644 --- a/Number_types/include/CGAL/CORE_coercion_traits.h +++ b/Number_types/include/CGAL/CORE_coercion_traits.h @@ -24,29 +24,11 @@ #include -//#include namespace CGAL { //CORE internal coercions: - -// The following definitions reflect the interaction of the CORE number types -// with the built in types, -// CORE BigInt: - CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short ,::CORE::BigInt) - CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int ,::CORE::BigInt) - CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long ,::CORE::BigInt) - - -// CORE BigRat: - CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short ,::CORE::BigRat) - CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int ,::CORE::BigRat) - CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long ,::CORE::BigRat) - CGAL_DEFINE_COERCION_TRAITS_FROM_TO(float ,::CORE::BigRat) - CGAL_DEFINE_COERCION_TRAITS_FROM_TO(double ,::CORE::BigRat) - CGAL_DEFINE_COERCION_TRAITS_FROM_TO(::CORE::BigInt,::CORE::BigRat) - // CORE Expr: CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short ,::CORE::Expr) CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int ,::CORE::Expr) @@ -75,12 +57,14 @@ struct Coercion_traits{ typedef Type result_type; Type operator()(const CORE::BigFloat& x) const { return x;} Type operator()(const ::CORE::BigInt x) const { - CORE::BigFloat result; - result.approx(x,CORE::get_static_defRelPrec().toLong(),LONG_MAX); - // Do not use MakeFloorExact as it changes the Bigfloat - CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()-result.err(),0,result.exp())) <= x ); - CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()+result.err(),0,result.exp())) >= x ); - return result; + CORE::BigFloat result; + result.approx(x,CORE::get_static_defRelPrec().toLong(),LONG_MAX); + // Do not use MakeFloorExact as it changes the Bigfloat + CGAL_postcondition_code(::CORE::BigRat r = ::CORE::BigFloat(result.m()-result.err(),0,result.exp())); + CGAL_postcondition( r <= x ); + CGAL_postcondition_code(::CORE::BigRat r2 = ::CORE::BigFloat(result.m()+result.err(),0,result.exp())); + CGAL_postcondition( r2 >= x ); + return result; } }; }; @@ -95,12 +79,13 @@ struct Coercion_traits{ typedef Type result_type; Type operator()(const CORE::BigFloat& x) const { return x;} Type operator()(const ::CORE::BigRat x) const { - CORE::BigFloat result(x,CORE::get_static_defRelPrec().toLong(),LONG_MAX); - // Do not use MakeFloorExact as it changes the Bigfloat - CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()-result.err(),0,result.exp())) <= x ); - CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()+result.err(),0,result.exp())) >= x ); - return result; + // Do not use MakeFloorExact as it changes the Bigfloat + CGAL_postcondition_code(::CORE::BigRat r = ::CORE::BigFloat(result.m()-result.err(),0,result.exp())); + CGAL_postcondition( r <= x ); + CGAL_postcondition_code(::CORE::BigRat r2 = ::CORE::BigFloat(result.m()+result.err(),0,result.exp())); + CGAL_postcondition( r2 >= x ); + return result; } }; }; @@ -115,11 +100,13 @@ struct Coercion_traits{ typedef Type result_type; Type operator()(const CORE::BigFloat& x) const { return x;} Type operator()(const ::CORE::Expr x) const { - CORE::BigFloat result(x, CORE::get_static_defRelPrec().toLong(),LONG_MAX); - // Do not use MakeFloorExact as it changes the Bigfloat - CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()-result.err(),0,result.exp())) <= x ); - CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()+result.err(),0,result.exp())) >= x ); - return result; + CORE::BigFloat result(x, CORE::get_static_defRelPrec().toLong(),LONG_MAX); + // Do not use MakeFloorExact as it changes the Bigfloat + CGAL_postcondition_code(::CORE::BigRat r = ::CORE::BigFloat(result.m()-result.err(),0,result.exp())); + CGAL_postcondition( r <= x ); + CGAL_postcondition_code(::CORE::BigRat r2 = ::CORE::BigFloat(result.m()+result.err(),0,result.exp())); + CGAL_postcondition( r2 >= x ); + return result; } }; }; @@ -150,6 +137,8 @@ template <> struct Coercion_traits< ::CORE::Expr, CORE::BigFloat > } //namespace CGAL + + #endif // CGAL_USE_CORE #endif //CGAL_CORE_COERCION_TRAITS_H 1 //EOF diff --git a/Number_types/include/CGAL/Counted_number.h b/Number_types/include/CGAL/Counted_number.h index bb3dc060f0e5..60b854fdc8f0 100644 --- a/Number_types/include/CGAL/Counted_number.h +++ b/Number_types/include/CGAL/Counted_number.h @@ -121,8 +121,12 @@ class Counted_number { Counted_number() {} //explicit Counted_number(int n) :m_rep(n){} explicit Counted_number(NT n) :m_rep(n){} + Counted_number operator-() const - {inc_neg_count();return Counted_number(-m_rep);} + { + inc_neg_count(); NT neg = -m_rep; return Counted_number(neg); + } + Counted_number const & operator+=(Counted_number const &n) { inc_add_count(); @@ -352,7 +356,7 @@ Counted_number operator+(Counted_number const &n1, Counted_number const &n2) { Counted_number::inc_add_count(); - return Counted_number(n1.rep() + n2.rep()); + return Counted_number(NT(n1.rep() + n2.rep())); } template @@ -360,7 +364,7 @@ Counted_number operator-(Counted_number const &n1, Counted_number const &n2) { Counted_number::inc_sub_count(); - return Counted_number(n1.rep() - n2.rep()); + return Counted_number(NT(n1.rep() - n2.rep())); } template @@ -368,7 +372,7 @@ Counted_number operator*(Counted_number const &n1, Counted_number const &n2) { Counted_number::inc_mul_count(); - return Counted_number(n1.rep() * n2.rep()); + return Counted_number(NT(n1.rep() * n2.rep())); } template @@ -376,7 +380,7 @@ Counted_number operator/(Counted_number const &n1, Counted_number const &n2) { Counted_number::inc_div_count(); - return Counted_number(n1.rep() / n2.rep()); + return Counted_number(NT(n1.rep() / n2.rep())); } template< class NT > diff --git a/Number_types/include/CGAL/Number_types/internal/Exact_type_selector.h b/Number_types/include/CGAL/Number_types/internal/Exact_type_selector.h index b0f645eb3a6e..d29278219dca 100644 --- a/Number_types/include/CGAL/Number_types/internal/Exact_type_selector.h +++ b/Number_types/include/CGAL/Number_types/internal/Exact_type_selector.h @@ -23,7 +23,9 @@ #include #include -#include +#ifdef CGAL_USE_BOOST_MP +#include +#endif #ifdef CGAL_USE_GMP # include diff --git a/Number_types/include/CGAL/Root_of_traits.h b/Number_types/include/CGAL/Root_of_traits.h index 32d81e481a97..239d580e7bfc 100644 --- a/Number_types/include/CGAL/Root_of_traits.h +++ b/Number_types/include/CGAL/Root_of_traits.h @@ -76,7 +76,9 @@ compute_roots_of_2(const NT &a_, const NT &b_, const NT &c_, OutputIterator oit) } } else { - *oit++ = -c/b; return oit; + Root_of_1 cb = -c / b; + *oit++ = Root_of_2(cb); + return oit; } } diff --git a/Number_types/include/CGAL/boost_mp.h b/Number_types/include/CGAL/boost_mp.h index b98980acbc59..42a06de04e77 100644 --- a/Number_types/include/CGAL/boost_mp.h +++ b/Number_types/include/CGAL/boost_mp.h @@ -12,902 +12,8 @@ #ifndef CGAL_BOOST_MP_H #define CGAL_BOOST_MP_H -#include -#include - -// It is easier to disable this number type completely for old versions. -// Before 1.63, I/O is broken. Again, disabling the whole file is just the -// easy solution. -// MSVC had trouble with versions <= 1.69: -// https://github.com/boostorg/multiprecision/issues/98 -// -// Disable also on Windows 32 bits -// because CGAL/cpp_float.h assumes _BitScanForward64 is available -// See https://learn.microsoft.com/en-us/cpp/intrinsics/bitscanforward-bitscanforward64 -// -// Disable also with PowerPC processors, with Boost<1.80 because of that bug: -// https://github.com/boostorg/multiprecision/pull/421 -// -#if !defined CGAL_DO_NOT_USE_BOOST_MP && \ - (!defined _MSC_VER || BOOST_VERSION >= 107000) && \ - (!defined _WIN32 || defined _WIN64) && \ - (BOOST_VERSION >= 108000 || (!defined _ARCH_PPC && !defined _ARCH_PPC64)) -#define CGAL_USE_BOOST_MP 1 - -#include -#include // *ary_function -#include -#include -// We can't just include all Boost.Multiprecision here... -#include -#include -// ... but we kind of have to :-( -#include -#ifdef CGAL_USE_GMP -// Same dance as in CGAL/gmp.h -# include -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable: 4127 4244 4146 4267) // conversion with loss of data - // warning on - applied on unsigned number -# endif - -# include - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif - -# include -#endif -#ifdef CGAL_USE_MPFR -# include -#endif - -// TODO: work on the coercions (end of the file) - -namespace CGAL { - -// Algebraic_structure_traits - -template ::value> > -struct AST_boost_mp; - -template -struct AST_boost_mp > - : Algebraic_structure_traits_base< NT, Euclidean_ring_tag > { - typedef NT Type; - typedef Euclidean_ring_tag Algebraic_category; - typedef Boolean_tag::is_exact> Is_exact; - typedef Tag_false Is_numerical_sensitive; - - struct Is_zero: public CGAL::cpp98::unary_function { - bool operator()( const Type& x) const { - return x.is_zero(); - } - }; - - struct Div: - public CGAL::cpp98::binary_function { - template - Type operator()(const T& x, const U& y) const { - return x / y; - } - }; - - struct Mod: - public CGAL::cpp98::binary_function { - template - Type operator()(const T& x, const U& y) const { - return x % y; - } - }; - - struct Gcd : public CGAL::cpp98::binary_function { - template - Type operator()(const T& x, const U& y) const { - return boost::multiprecision::gcd(x, y); - } - }; - - struct Sqrt : public CGAL::cpp98::unary_function { - template - Type operator()(const T& x) const { - return boost::multiprecision::sqrt(x); - } - }; -}; - -template -struct AST_boost_mp > - : public Algebraic_structure_traits_base< NT , Field_tag > { - public: - typedef NT Type; - typedef Field_tag Algebraic_category; - typedef Tag_true Is_exact; - typedef Tag_false Is_numerical_sensitive; - - struct Is_zero: public CGAL::cpp98::unary_function { - bool operator()( const Type& x) const { - return x.is_zero(); - } - }; - - struct Div: - public CGAL::cpp98::binary_function { - template - Type operator()(const T& x, const U& y) const { - return x / y; - } - }; -}; - -template -struct Algebraic_structure_traits > -: AST_boost_mp > {}; -template -struct Algebraic_structure_traits > -: Algebraic_structure_traits::result_type > {}; - -// Real_embeddable_traits - -namespace Boost_MP_internal { - - // here we know that `intv` contains int64 numbers such that their msb is std::numeric_limits::digits-1 - // TODO: possibly return denormals sometimes... - inline - std::pair shift_positive_interval( const std::pair& intv, const int e ) { - CGAL_assertion(intv.first > 0.0); - CGAL_assertion(intv.second > 0.0); - -#ifdef CGAL_LITTLE_ENDIAN - CGAL_assertion_code( - union { - struct { uint64_t man:52; uint64_t exp:11; uint64_t sig:1; } s; - double d; - } conv; - - conv.d = intv.first; - ) -#else - //WARNING: untested! - CGAL_assertion_code( - union { - - struct { uint64_t sig:1; uint64_t exp:11; uint64_t man:52; } s; - double d; - } conv; - - conv.d = intv.first; - ) -#endif - // Check that the exponent of intv.inf is 52, which corresponds to a 53 bit integer - CGAL_assertion(conv.s.exp - ((1 << (11 - 1)) - 1) == std::numeric_limits::digits - 1); - - typedef std::numeric_limits limits; - - // warning: min_exponent and max_exponent are 1 more than what the name suggests - if (e < limits::min_exponent - limits::digits) - return {0, (limits::min)()}; - if (e > limits::max_exponent - limits::digits) - return {(limits::max)(), limits::infinity()}; // intv is positive - - const double scale = std::ldexp(1.0, e); // ldexp call is exact - return { scale * intv.first, scale * intv.second }; // cases that would require a rounding mode have been handled above - } - - // This function checks if the computed interval is correct and if it is tight. - template - bool are_bounds_correct( const double l, const double u, const Type& x ) { - typedef std::numeric_limits limits; - - const double inf = std::numeric_limits::infinity(); - if ( u!=l && (l==-inf || u==inf - || (u==0 && l >= -(limits::min)()) - || (l==0 && u <= (limits::min)())) ) - { - return x > Type((limits::max)()) || - x < Type(-(limits::max)()) || - (x > Type(-(limits::min)()) && x < Type((limits::min)())); - } - - if (!(u == l || u == std::nextafter(l, +inf))) return false; - //TODO: Type(nextafter(l,inf))>x && Type(nextafter(u,-inf)) get_0ulp_interval( const int shift, const uint64_t p ) { - - const double pp_dbl = static_cast(p); - const std::pair intv(pp_dbl, pp_dbl); - - return shift_positive_interval(intv, -shift); - } - - // This one returns 1 unit length interval. - inline - std::pair get_1ulp_interval( const int shift, const uint64_t p ) { - - const double pp_dbl = static_cast(p); - const double qq_dbl = pp_dbl+1; - const std::pair intv(pp_dbl, qq_dbl); - return shift_positive_interval(intv, -shift); - } - - template - std::pair to_interval( ET x, int extra_shift = 0 ); - - // This is a version of to_interval that converts a rational type into a - // double tight interval. - template - std::pair to_interval( ET xnum, ET xden ) { - - CGAL_assertion(!CGAL::is_zero(xden)); - CGAL_assertion_code(const Type input(xnum, xden)); - double l = 0.0, u = 0.0; - if (CGAL::is_zero(xnum)) { // return [0.0, 0.0] - CGAL_assertion(are_bounds_correct(l, u, input)); - return std::make_pair(l, u); - } - CGAL_assertion(!CGAL::is_zero(xnum)); - - // Handle signs. - bool change_sign = false; - const bool is_num_pos = CGAL::is_positive(xnum); - const bool is_den_pos = CGAL::is_positive(xden); - if (!is_num_pos && !is_den_pos) { - xnum = -xnum; - xden = -xden; - } else if (!is_num_pos && is_den_pos) { - change_sign = true; - xnum = -xnum; - } else if (is_num_pos && !is_den_pos) { - change_sign = true; - xden = -xden; - } - CGAL_assertion(CGAL::is_positive(xnum) && CGAL::is_positive(xden)); - - const int64_t num_dbl_digits = std::numeric_limits::digits - 1; - const int64_t msb_num = static_cast(boost::multiprecision::msb(xnum)); - const int64_t msb_den = static_cast(boost::multiprecision::msb(xden)); - -#if 0 // Optimisation for the case of input that are double - // An alternative strategy would be to convert numerator and denominator to - // intervals, then divide. However, this would require setting the rounding - // mode (and dividing intervals is not completely free). An important - // special case is when the rational is exactly equal to a double - // (fit_in_double). Then the denominator is a power of 2, so we can skip - // the division and it becomes unnecessary to set the rounding mode, we - // just need to modify the exponent correction for the denominator. - if(msb_den == static_cast(lsb(xden))) { - std::tie(l,u)=to_interval(xnum, msb_den); - if (change_sign) { - CGAL_assertion(are_bounds_correct(-u, -l, input)); - return {-u, -l}; - } - CGAL_assertion(are_bounds_correct(l, u, input)); - return {u, l}; - } -#endif - - const int64_t msb_diff = msb_num - msb_den; - // Shift so the division result has at least 53 (and at most 54) bits - int shift = static_cast(num_dbl_digits - msb_diff + 1); - CGAL_assertion(shift == num_dbl_digits - msb_diff + 1); - - if (shift > 0) { - xnum <<= +shift; - } else if (shift < 0) { - xden <<= -shift; - } - CGAL_assertion(num_dbl_digits + 1 == - static_cast(boost::multiprecision::msb(xnum)) - - static_cast(boost::multiprecision::msb(xden))); - - ET p, r; - boost::multiprecision::divide_qr(xnum, xden, p, r); - uint64_t uip = static_cast(p); - const int64_t p_bits = static_cast(boost::multiprecision::msb(p)); - bool exact = r.is_zero(); - - if (p_bits > num_dbl_digits) { // case 54 bits - exact &= ((uip & 1) == 0); - uip>>=1; - --shift; - } - std::tie(l, u) = exact ? get_0ulp_interval(shift, uip) : get_1ulp_interval(shift, uip); - - if (change_sign) { - const double t = l; - l = -u; - u = -t; - } - - CGAL_assertion(are_bounds_correct(l, u, input)); - return std::make_pair(l, u); - } - - // This is a version of to_interval that converts an integer type into a - // double tight interval. - template - std::pair to_interval( ET x, int extra_shift) { - - CGAL_assertion_code(const ET input = x); - double l = 0.0, u = 0.0; - if (CGAL::is_zero(x)) { // return [0.0, 0.0] - CGAL_assertion(are_bounds_correct(l, u, input)); - return std::make_pair(l, u); - } - CGAL_assertion(!CGAL::is_zero(x)); - - bool change_sign = false; - const bool is_pos = CGAL::is_positive(x); - if (!is_pos) { - change_sign = true; - x = -x; - } - CGAL_assertion(CGAL::is_positive(x)); - - const int64_t n = static_cast(boost::multiprecision::msb(x)) + 1; - const int64_t num_dbl_digits = std::numeric_limits::digits; - - if (n > num_dbl_digits) { - const int64_t mindig = static_cast(boost::multiprecision::lsb(x)); - int e = static_cast(n - num_dbl_digits); - x >>= e; - if (n - mindig > num_dbl_digits) - std::tie(l, u) = get_1ulp_interval(-e+extra_shift, static_cast(x)); - else - std::tie(l, u) = get_0ulp_interval(-e+extra_shift, static_cast(x)); - } else { - l = u = extra_shift==0 ? static_cast(static_cast(x)) - : std::ldexp(static_cast(static_cast(x)),-extra_shift); - } - - if (change_sign) { - const double t = l; - l = -u; - u = -t; - } - - CGAL_assertion(extra_shift != 0 || are_bounds_correct(l, u, input)); - return std::make_pair(l, u); - } - -} // Boost_MP_internal - -template -struct RET_boost_mp_base - : public INTERN_RET::Real_embeddable_traits_base< NT , CGAL::Tag_true > { - - typedef NT Type; - - struct Is_zero: public CGAL::cpp98::unary_function { - bool operator()( const Type& x) const { - return x.is_zero(); - } - }; - - struct Is_positive: public CGAL::cpp98::unary_function { - bool operator()( const Type& x) const { - return x.sign() > 0; - } - }; - - struct Is_negative: public CGAL::cpp98::unary_function { - bool operator()( const Type& x) const { - return x.sign() < 0; - } - }; - - struct Abs : public CGAL::cpp98::unary_function { - template - Type operator()(const T& x) const { - return boost::multiprecision::abs(x); - } - }; - - struct Sgn : public CGAL::cpp98::unary_function { - ::CGAL::Sign operator()(Type const& x) const { - return CGAL::sign(x.sign()); - } - }; - - struct Compare - : public CGAL::cpp98::binary_function { - Comparison_result operator()(const Type& x, const Type& y) const { - return CGAL::sign(x.compare(y)); - } - }; - - struct To_double - : public CGAL::cpp98::unary_function { - double operator()(const Type& x) const { - return x.template convert_to(); - } - }; - - struct To_interval - : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { - - std::pair - operator()(const Type& x) const { - - // See if https://github.com/boostorg/multiprecision/issues/108 suggests anything better - // assume the conversion is within 1 ulp - // adding IA::smallest() doesn't work because inf-e=inf, even rounded down. - - // We must use to_nearest here. - double i; - const double inf = std::numeric_limits::infinity(); - { - Protect_FPU_rounding P(CGAL_FE_TONEAREST); - i = static_cast(x); - if (i == +inf) { - return std::make_pair((std::numeric_limits::max)(), i); - } else if (i == -inf) { - return std::make_pair(i, std::numeric_limits::lowest()); - } - } - double s = i; - CGAL_assertion(CGAL::abs(i) != inf && CGAL::abs(s) != inf); - - // Throws uncaught exception: Cannot convert a non-finite number to an integer. - // We can catch it earlier by using the CGAL_assertion() one line above. - const int cmp = x.compare(i); - if (cmp > 0) { - s = nextafter(s, +inf); - CGAL_assertion(x.compare(s) < 0); - } - else if (cmp < 0) { - i = nextafter(i, -inf); - CGAL_assertion(x.compare(i) > 0); - } - return std::pair(i, s); - } - }; -}; - -template ::value> > -struct RET_boost_mp; - -template -struct RET_boost_mp > - : RET_boost_mp_base { - typedef NT Type; - struct To_interval - : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { - - std::pair operator()( const Type& x ) const { - return Boost_MP_internal::to_interval(x); - } - }; -}; - -template -struct RET_boost_mp > - : RET_boost_mp_base { - typedef NT Type; - struct To_interval - : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { - - std::pair operator()( const Type& x ) const { - return Boost_MP_internal::to_interval( - boost::multiprecision::numerator(x), boost::multiprecision::denominator(x)); - } - }; -}; - -#ifdef CGAL_USE_MPFR -// Because of these full specializations, things get instantiated more eagerly. Make them artificially partial if necessary. -template <> -struct RET_boost_mp - : RET_boost_mp_base { - typedef boost::multiprecision::mpz_int Type; - struct To_interval - : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { - std::pair - operator()(const Type& x) const { -#if MPFR_VERSION_MAJOR >= 3 - MPFR_DECL_INIT (y, 53); /* Assume IEEE-754 */ - int r = mpfr_set_z (y, x.backend().data(), MPFR_RNDA); - double i = mpfr_get_d (y, MPFR_RNDA); /* EXACT but can overflow */ - if (r == 0 && is_finite (i)) - return std::pair(i, i); - else - { - double s = nextafter (i, 0); - if (i < 0) - return std::pair(i, s); - else - return std::pair(s, i); - } -#else - mpfr_t y; - mpfr_init2 (y, 53); /* Assume IEEE-754 */ - mpfr_set_z (y, x.backend().data(), GMP_RNDD); - double i = mpfr_get_d (y, GMP_RNDD); /* EXACT but can overflow */ - mpfr_set_z (y, x.backend().data(), GMP_RNDU); - double s = mpfr_get_d (y, GMP_RNDU); /* EXACT but can overflow */ - mpfr_clear (y); - return std::pair(i, s); -#endif - } - }; -}; -template <> -struct RET_boost_mp - : RET_boost_mp_base { - typedef boost::multiprecision::mpq_rational Type; - struct To_interval - : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { - std::pair - operator()(const Type& x) const { -# if MPFR_VERSION_MAJOR >= 3 - mpfr_exp_t emin = mpfr_get_emin(); - mpfr_set_emin(-1073); - MPFR_DECL_INIT (y, 53); /* Assume IEEE-754 */ - int r = mpfr_set_q (y, x.backend().data(), MPFR_RNDA); - r = mpfr_subnormalize (y, r, MPFR_RNDA); /* Round subnormals */ - double i = mpfr_get_d (y, MPFR_RNDA); /* EXACT but can overflow */ - mpfr_set_emin(emin); /* Restore old value, users may care */ - // With mpfr_set_emax(1024) we could drop the is_finite test - if (r == 0 && is_finite (i)) - return std::pair(i, i); - else - { - double s = nextafter (i, 0); - if (i < 0) - return std::pair(i, s); - else - return std::pair(s, i); - } -# else - mpfr_t y; - mpfr_init2 (y, 53); /* Assume IEEE-754 */ - mpfr_set_q (y, x.backend().data(), GMP_RNDD); - double i = mpfr_get_d (y, GMP_RNDD); /* EXACT but can overflow */ - mpfr_set_q (y, x.backend().data(), GMP_RNDU); - double s = mpfr_get_d (y, GMP_RNDU); /* EXACT but can overflow */ - mpfr_clear (y); - return std::pair(i, s); -# endif - } - }; -}; -#endif - -template -struct Real_embeddable_traits > -: RET_boost_mp > {}; -template -struct Real_embeddable_traits > -: Real_embeddable_traits::result_type > {}; - -// Modular_traits - -template ::value> > -struct MT_boost_mp { - typedef T NT; - typedef ::CGAL::Tag_false Is_modularizable; - typedef ::CGAL::Null_functor Residue_type; - typedef ::CGAL::Null_functor Modular_image; - typedef ::CGAL::Null_functor Modular_image_representative; -}; - -template -struct MT_boost_mp > { - typedef T NT; - typedef CGAL::Tag_true Is_modularizable; - typedef Residue Residue_type; - - struct Modular_image{ - Residue_type operator()(const NT& a){ - NT tmp(CGAL::mod(a,NT(Residue::get_current_prime()))); - return CGAL::Residue(tmp.template convert_to()); - } - }; - struct Modular_image_representative{ - NT operator()(const Residue_type& x){ - return NT(x.get_value()); - } - }; -}; - -template -struct Modular_traits > -: MT_boost_mp > {}; -template -struct Modular_traits > -: Modular_traits::result_type > {}; - -// Split_double - -template ::value> > -struct SD_boost_mp { - void operator()(double d, NT &num, NT &den) const - { - num = d; - den = 1; - } -}; - -template -struct SD_boost_mp > -{ - void operator()(double d, NT &num, NT &den) const - { - std::pair p = split_numerator_denominator(d); - num = NT(p.first); - den = NT(p.second); - } -}; - -template -struct Split_double > -: SD_boost_mp > {}; -template -struct Split_double > -: Split_double::result_type > {}; - - -// Fraction_traits - -template ::value> > -struct FT_boost_mp { - typedef T Type; - typedef Tag_false Is_fraction; - typedef Null_tag Numerator_type; - typedef Null_tag Denominator_type; - typedef Null_functor Common_factor; - typedef Null_functor Decompose; - typedef Null_functor Compose; -}; - -template -struct FT_boost_mp > { - typedef NT Type; - - typedef ::CGAL::Tag_true Is_fraction; - typedef typename boost::multiprecision::component_type::type Numerator_type; - typedef Numerator_type Denominator_type; - - typedef typename Algebraic_structure_traits< Numerator_type >::Gcd Common_factor; - - class Decompose { - public: - typedef Type first_argument_type; - typedef Numerator_type& second_argument_type; - typedef Denominator_type& third_argument_type; - void operator () ( - const Type& rat, - Numerator_type& num, - Denominator_type& den) { - num = numerator(rat); - den = denominator(rat); - } - }; - - class Compose { - public: - typedef Numerator_type first_argument_type; - typedef Denominator_type second_argument_type; - typedef Type result_type; - Type operator ()( - const Numerator_type& num , - const Denominator_type& den ) { - return Type(num, den); - } - }; -}; - -template -struct Fraction_traits > -: FT_boost_mp > {}; -template -struct Fraction_traits > -: Fraction_traits::result_type > {}; - - -// Coercions - -namespace internal { namespace boost_mp { BOOST_MPL_HAS_XXX_TRAIT_DEF(type) } } - -template -struct Coercion_traits, boost::multiprecision::number > -{ - typedef boost::common_type, boost::multiprecision::number > CT; - typedef Boolean_tag::value> Are_implicit_interoperable; - // FIXME: the implicit/explicit answers shouldn't be the same... - typedef Are_implicit_interoperable Are_explicit_interoperable; - // FIXME: won't compile when they are not interoperable. - typedef typename CT::type Type; - struct Cast{ - typedef Type result_type; - template - Type operator()(const U& x) const { - return Type(x); - } - }; -}; -// Avoid ambiguity with the specialization for ... -template -struct Coercion_traits, boost::multiprecision::number > -{ - typedef boost::multiprecision::number Type; - typedef Tag_true Are_implicit_interoperable; - typedef Tag_true Are_explicit_interoperable; - struct Cast{ - typedef Type result_type; - template - Type operator()(const U& x) const { - return Type(x); - } - }; -}; - -template -struct Coercion_traits < -boost::multiprecision::detail::expression, -boost::multiprecision::detail::expression > -: Coercion_traits < -typename boost::multiprecision::detail::expression::result_type, -typename boost::multiprecision::detail::expression::result_type> -{ }; -// Avoid ambiguity with the specialization for ... -template -struct Coercion_traits < -boost::multiprecision::detail::expression, -boost::multiprecision::detail::expression > -: Coercion_traits < -typename boost::multiprecision::detail::expression::result_type, -typename boost::multiprecision::detail::expression::result_type> -{ }; - -template -struct Coercion_traits, boost::multiprecision::detail::expression > -: Coercion_traits < -boost::multiprecision::number, -typename boost::multiprecision::detail::expression::result_type> -{ }; - -template -struct Coercion_traits, boost::multiprecision::number > -: Coercion_traits < -typename boost::multiprecision::detail::expression::result_type, -boost::multiprecision::number > -{ }; - -// TODO: fix existing coercions -// (double -> rational is implicit only for 1.56+, see ticket #10082) -// The real solution would be to avoid specializing Coercion_traits for all pairs of number types and let it auto-detect what works, so only broken types need an explicit specialization. - -// Ignore types smaller than long -#define CGAL_COERCE_INT(int) \ -template \ -struct Coercion_traits, int> { \ - typedef boost::multiprecision::number Type; \ - typedef Tag_true Are_implicit_interoperable; \ - typedef Tag_true Are_explicit_interoperable; \ - struct Cast{ \ - typedef Type result_type; \ - template Type operator()(const U& x) const { return Type(x); } \ - }; \ -}; \ -template \ -struct Coercion_traits > \ -: Coercion_traits, int> {}; \ -template \ -struct Coercion_traits, int> \ -: Coercion_traits::result_type, int>{}; \ -template \ -struct Coercion_traits > \ -: Coercion_traits::result_type, int>{} - -CGAL_COERCE_INT(short); -CGAL_COERCE_INT(int); -CGAL_COERCE_INT(long); -#undef CGAL_COERCE_INT - -// Ignore bounded-precision rationals -#define CGAL_COERCE_FLOAT(float) \ -template \ -struct Coercion_traits, float> { \ - typedef boost::multiprecision::number Type; \ - typedef Boolean_tag::value != boost::multiprecision::number_kind_integer> Are_implicit_interoperable; \ - typedef Are_implicit_interoperable Are_explicit_interoperable; \ - struct Cast{ \ - typedef Type result_type; \ - template Type operator()(const U& x) const { return Type(x); } \ - }; \ -}; \ -template \ -struct Coercion_traits > \ -: Coercion_traits, float> {}; \ -template \ -struct Coercion_traits, float> \ -: Coercion_traits::result_type, float>{}; \ -template \ -struct Coercion_traits > \ -: Coercion_traits::result_type, float>{} - -CGAL_COERCE_FLOAT(float); -CGAL_COERCE_FLOAT(double); -#undef CGAL_COERCE_FLOAT - -// Because of https://github.com/boostorg/multiprecision/issues/29 , this is not perfect and fails to read some KDS files. - -template <> -class Input_rep : public IO_rep_is_specialized { - boost::multiprecision::cpp_rational& q; -public: - Input_rep(boost::multiprecision::cpp_rational& qq) : q(qq) {} - std::istream& operator()(std::istream& in) const { - internal::read_float_or_quotient(in, q); - return in; - } -}; -#ifdef CGAL_USE_GMP -template <> -class Input_rep : public IO_rep_is_specialized { - boost::multiprecision::mpq_rational& q; -public: - Input_rep(boost::multiprecision::mpq_rational& qq) : q(qq) {} - std::istream& operator()(std::istream& in) const { - internal::read_float_or_quotient(in, q); - return in; - } -}; -#endif - -// Copied from leda_rational.h -namespace internal { - // See: Stream_support/include/CGAL/IO/io.h - template - void read_float_or_quotient(std::istream & is, ET& et); - - template <> - inline void read_float_or_quotient(std::istream & is, boost::multiprecision::cpp_rational& et) - { - internal::read_float_or_quotient(is, et); - } -#ifdef CGAL_USE_GMP - template <> - inline void read_float_or_quotient(std::istream & is, boost::multiprecision::mpq_rational& et) - { - internal::read_float_or_quotient(is, et); - } -#endif -} // namespace internal - -#ifdef CGAL_USE_BOOST_MP - -template< > class Real_embeddable_traits< Quotient > - : public INTERN_QUOTIENT::Real_embeddable_traits_quotient_base< Quotient > { - - public: - typedef Quotient Type; - - class To_interval - : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { - public: - std::pair operator()( const Type& x ) const { - return Boost_MP_internal::to_interval(x.num, x.den); - } - }; -}; - -#endif // CGAL_USE_BOOST_MP - -} //namespace CGAL - +#include #include #include -#endif // BOOST_VERSION -#endif +#endif // CGAL_BOOST_MP_H diff --git a/Number_types/include/CGAL/boost_mp_type.h b/Number_types/include/CGAL/boost_mp_type.h new file mode 100644 index 000000000000..cf18678c0114 --- /dev/null +++ b/Number_types/include/CGAL/boost_mp_type.h @@ -0,0 +1,1027 @@ +// Copyright (c) 2017 +// INRIA Saclay-Ile de France (France), +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Marc Glisse + +#ifndef CGAL_BOOST_MP_TYPE_H +#define CGAL_BOOST_MP_TYPE_H + +#include +#include + +// CGAL_USE_BOOST_MP is defined in +// CGAL/Installation/internal/enable_third_party_libraries.h +#if CGAL_USE_BOOST_MP + +#include +#include // *ary_function +#include +#include +// We can't just include all Boost.Multiprecision here... +#include +#include +// ... but we kind of have to :-( +#include +#ifdef CGAL_USE_GMP +// Same dance as in CGAL/gmp.h +# include +# if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable: 4127 4244 4146 4267) // conversion with loss of data + // warning on - applied on unsigned number +# endif + +# include + +# if defined(BOOST_MSVC) +# pragma warning(pop) +# endif + +# include +#endif +#ifdef CGAL_USE_MPFR +# include +#endif + +// TODO: work on the coercions (end of the file) + +namespace CGAL { +template<> +struct Needs_parens_as_product{ + bool operator()(const typename boost::multiprecision::cpp_int& x){ + return x < 0; + } +}; + +template<> +struct Needs_parens_as_product{ + bool operator()(const typename boost::multiprecision::cpp_rational& x){ + if (denominator(x) != 1 ) + return true; + else + return needs_parens_as_product(numerator(x)) ; + } + +}; + +#ifdef CGAL_USE_GMP +template<> +struct Needs_parens_as_product{ + bool operator()(const typename boost::multiprecision::mpz_int& x){ + return x < 0; + } +}; + +template<> +struct Needs_parens_as_product{ + bool operator()(const typename boost::multiprecision::mpq_rational& x){ + if (denominator(x) != 1 ) + return true; + else + return needs_parens_as_product(numerator(x)) ; + } +}; +#endif + + + +// Algebraic_structure_traits + +template ::value> > +struct AST_boost_mp; + +template +struct AST_boost_mp > + : Algebraic_structure_traits_base< NT, Euclidean_ring_tag > { + typedef NT Type; + typedef Euclidean_ring_tag Algebraic_category; + typedef Boolean_tag::is_exact> Is_exact; + typedef Tag_false Is_numerical_sensitive; + + typedef INTERN_AST::Is_square_per_sqrt< Type > Is_square; + + struct Is_zero: public CGAL::cpp98::unary_function { + bool operator()( const Type& x) const { + return x.is_zero(); + } + }; + + struct Div: + public CGAL::cpp98::binary_function { + template + Type operator()(const T& x, const U& y) const { + return x / y; + } + }; + + struct Mod: + public CGAL::cpp98::binary_function { + template + Type operator()(const T& x, const U& y) const { + return x % y; + } + }; + + struct Gcd : public CGAL::cpp98::binary_function { + template + Type operator()(const T& x, const U& y) const { + return boost::multiprecision::gcd(x, y); + } + }; + + struct Sqrt : public CGAL::cpp98::unary_function { + template + Type operator()(const T& x) const { + return boost::multiprecision::sqrt(x); + } + }; +}; + +template +struct AST_boost_mp > + : public Algebraic_structure_traits_base< NT , Field_tag > { + public: + typedef NT Type; + typedef Field_tag Algebraic_category; + typedef Tag_true Is_exact; + typedef Tag_false Is_numerical_sensitive; + + struct Is_zero: public CGAL::cpp98::unary_function { + bool operator()( const Type& x) const { + return x.is_zero(); + } + }; + + struct Div: + public CGAL::cpp98::binary_function { + template + Type operator()(const T& x, const U& y) const { + return x / y; + } + }; +}; + +template +struct Algebraic_structure_traits > +: AST_boost_mp > {}; +template +struct Algebraic_structure_traits > +: Algebraic_structure_traits::result_type > {}; + +// Real_embeddable_traits + +namespace Boost_MP_internal { + + // here we know that `intv` contains int64 numbers such that their msb is std::numeric_limits::digits-1 + // TODO: possibly return denormals sometimes... + inline + std::pair shift_positive_interval( const std::pair& intv, const int e ) { + CGAL_assertion(intv.first > 0.0); + CGAL_assertion(intv.second > 0.0); + +#ifdef CGAL_LITTLE_ENDIAN + CGAL_assertion_code( + union { + struct { uint64_t man:52; uint64_t exp:11; uint64_t sig:1; } s; + double d; + } conv; + + conv.d = intv.first; + ) +#else + //WARNING: untested! + CGAL_assertion_code( + union { + + struct { uint64_t sig:1; uint64_t exp:11; uint64_t man:52; } s; + double d; + } conv; + + conv.d = intv.first; + ) +#endif + // Check that the exponent of intv.inf is 52, which corresponds to a 53 bit integer + CGAL_assertion(conv.s.exp - ((1 << (11 - 1)) - 1) == std::numeric_limits::digits - 1); + + typedef std::numeric_limits limits; + + // warning: min_exponent and max_exponent are 1 more than what the name suggests + if (e < limits::min_exponent - limits::digits) + return {0, (limits::min)()}; + if (e > limits::max_exponent - limits::digits) + return {(limits::max)(), limits::infinity()}; // intv is positive + + const double scale = std::ldexp(1.0, e); // ldexp call is exact + return { scale * intv.first, scale * intv.second }; // cases that would require a rounding mode have been handled above + } + + // This function checks if the computed interval is correct and if it is tight. + template + bool are_bounds_correct( const double l, const double u, const Type& x ) { + typedef std::numeric_limits limits; + + const double inf = std::numeric_limits::infinity(); + if ( u!=l && (l==-inf || u==inf + || (u==0 && l >= -(limits::min)()) + || (l==0 && u <= (limits::min)())) ) + { + return x > Type((limits::max)()) || + x < Type(-(limits::max)()) || + (x > Type(-(limits::min)()) && x < Type((limits::min)())); + } + + if (!(u == l || u == std::nextafter(l, +inf))) return false; + //TODO: Type(nextafter(l,inf))>x && Type(nextafter(u,-inf)) get_0ulp_interval( const int shift, const uint64_t p ) { + + const double pp_dbl = static_cast(p); + const std::pair intv(pp_dbl, pp_dbl); + + return shift_positive_interval(intv, -shift); + } + + // This one returns 1 unit length interval. + inline + std::pair get_1ulp_interval( const int shift, const uint64_t p ) { + + const double pp_dbl = static_cast(p); + const double qq_dbl = pp_dbl+1; + const std::pair intv(pp_dbl, qq_dbl); + return shift_positive_interval(intv, -shift); + } + + template + std::pair to_interval( ET x, int extra_shift = 0 ); + + // This is a version of to_interval that converts a rational type into a + // double tight interval. + template + std::pair to_interval( ET xnum, ET xden ) { + + CGAL_assertion(!CGAL::is_zero(xden)); + CGAL_assertion_code(const Type input(xnum, xden)); + double l = 0.0, u = 0.0; + if (CGAL::is_zero(xnum)) { // return [0.0, 0.0] + CGAL_assertion(are_bounds_correct(l, u, input)); + return std::make_pair(l, u); + } + CGAL_assertion(!CGAL::is_zero(xnum)); + + // Handle signs. + bool change_sign = false; + const bool is_num_pos = CGAL::is_positive(xnum); + const bool is_den_pos = CGAL::is_positive(xden); + if (!is_num_pos && !is_den_pos) { + xnum = -xnum; + xden = -xden; + } else if (!is_num_pos && is_den_pos) { + change_sign = true; + xnum = -xnum; + } else if (is_num_pos && !is_den_pos) { + change_sign = true; + xden = -xden; + } + CGAL_assertion(CGAL::is_positive(xnum) && CGAL::is_positive(xden)); + + const int64_t num_dbl_digits = std::numeric_limits::digits - 1; + const int64_t msb_num = static_cast(boost::multiprecision::msb(xnum)); + const int64_t msb_den = static_cast(boost::multiprecision::msb(xden)); + +#if 0 // Optimisation for the case of input that are double + // An alternative strategy would be to convert numerator and denominator to + // intervals, then divide. However, this would require setting the rounding + // mode (and dividing intervals is not completely free). An important + // special case is when the rational is exactly equal to a double + // (fit_in_double). Then the denominator is a power of 2, so we can skip + // the division and it becomes unnecessary to set the rounding mode, we + // just need to modify the exponent correction for the denominator. + if(msb_den == static_cast(lsb(xden))) { + std::tie(l,u)=to_interval(xnum, msb_den); + if (change_sign) { + CGAL_assertion(are_bounds_correct(-u, -l, input)); + return {-u, -l}; + } + CGAL_assertion(are_bounds_correct(l, u, input)); + return {u, l}; + } +#endif + + const int64_t msb_diff = msb_num - msb_den; + // Shift so the division result has at least 53 (and at most 54) bits + int shift = static_cast(num_dbl_digits - msb_diff + 1); + CGAL_assertion(shift == num_dbl_digits - msb_diff + 1); + + if (shift > 0) { + xnum <<= +shift; + } else if (shift < 0) { + xden <<= -shift; + } + CGAL_assertion(num_dbl_digits + 1 == + static_cast(boost::multiprecision::msb(xnum)) - + static_cast(boost::multiprecision::msb(xden))); + + ET p, r; + boost::multiprecision::divide_qr(xnum, xden, p, r); + uint64_t uip = static_cast(p); + const int64_t p_bits = static_cast(boost::multiprecision::msb(p)); + bool exact = r.is_zero(); + + if (p_bits > num_dbl_digits) { // case 54 bits + exact &= ((uip & 1) == 0); + uip>>=1; + --shift; + } + std::tie(l, u) = exact ? get_0ulp_interval(shift, uip) : get_1ulp_interval(shift, uip); + + if (change_sign) { + const double t = l; + l = -u; + u = -t; + } + + CGAL_assertion(are_bounds_correct(l, u, input)); + return std::make_pair(l, u); + } + + // This is a version of to_interval that converts an integer type into a + // double tight interval. + template + std::pair to_interval( ET x, int extra_shift) { + + CGAL_assertion_code(const ET input = x); + double l = 0.0, u = 0.0; + if (CGAL::is_zero(x)) { // return [0.0, 0.0] + CGAL_assertion(are_bounds_correct(l, u, input)); + return std::make_pair(l, u); + } + CGAL_assertion(!CGAL::is_zero(x)); + + bool change_sign = false; + const bool is_pos = CGAL::is_positive(x); + if (!is_pos) { + change_sign = true; + x = -x; + } + CGAL_assertion(CGAL::is_positive(x)); + + const int64_t n = static_cast(boost::multiprecision::msb(x)) + 1; + const int64_t num_dbl_digits = std::numeric_limits::digits; + + if (n > num_dbl_digits) { + const int64_t mindig = static_cast(boost::multiprecision::lsb(x)); + int e = static_cast(n - num_dbl_digits); + x >>= e; + if (n - mindig > num_dbl_digits) + std::tie(l, u) = get_1ulp_interval(-e+extra_shift, static_cast(x)); + else + std::tie(l, u) = get_0ulp_interval(-e+extra_shift, static_cast(x)); + } else { + l = u = extra_shift==0 ? static_cast(static_cast(x)) + : std::ldexp(static_cast(static_cast(x)),-extra_shift); + } + + if (change_sign) { + const double t = l; + l = -u; + u = -t; + } + + CGAL_assertion(extra_shift != 0 || are_bounds_correct(l, u, input)); + return std::make_pair(l, u); + } + +} // Boost_MP_internal + +template +struct RET_boost_mp_base + : public INTERN_RET::Real_embeddable_traits_base< NT , CGAL::Tag_true > { + + typedef NT Type; + + struct Is_zero: public CGAL::cpp98::unary_function { + bool operator()( const Type& x) const { + return x.is_zero(); + } + }; + + struct Is_positive: public CGAL::cpp98::unary_function { + bool operator()( const Type& x) const { + return x.sign() > 0; + } + }; + + struct Is_negative: public CGAL::cpp98::unary_function { + bool operator()( const Type& x) const { + return x.sign() < 0; + } + }; + + struct Abs : public CGAL::cpp98::unary_function { + template + Type operator()(const T& x) const { + return boost::multiprecision::abs(x); + } + }; + + struct Sgn : public CGAL::cpp98::unary_function { + ::CGAL::Sign operator()(Type const& x) const { + return CGAL::sign(x.sign()); + } + }; + + struct Compare + : public CGAL::cpp98::binary_function { + Comparison_result operator()(const Type& x, const Type& y) const { + return CGAL::sign(x.compare(y)); + } + }; + + struct To_double + : public CGAL::cpp98::unary_function { + double operator()(const Type& x) const { + return x.template convert_to(); + } + }; + + struct To_interval + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { + + std::pair + operator()(const Type& x) const { + + // See if https://github.com/boostorg/multiprecision/issues/108 suggests anything better + // assume the conversion is within 1 ulp + // adding IA::smallest() doesn't work because inf-e=inf, even rounded down. + + // We must use to_nearest here. + double i; + const double inf = std::numeric_limits::infinity(); + { + Protect_FPU_rounding P(CGAL_FE_TONEAREST); + i = static_cast(x); + if (i == +inf) { + return std::make_pair((std::numeric_limits::max)(), i); + } else if (i == -inf) { + return std::make_pair(i, std::numeric_limits::lowest()); + } + } + double s = i; + CGAL_assertion(CGAL::abs(i) != inf && CGAL::abs(s) != inf); + + // Throws uncaught exception: Cannot convert a non-finite number to an integer. + // We can catch it earlier by using the CGAL_assertion() one line above. + const int cmp = x.compare(i); + if (cmp > 0) { + s = nextafter(s, +inf); + CGAL_assertion(x.compare(s) < 0); + } + else if (cmp < 0) { + i = nextafter(i, -inf); + CGAL_assertion(x.compare(i) > 0); + } + return std::pair(i, s); + } + }; +}; + +template ::value> > +struct RET_boost_mp; + +template +struct RET_boost_mp > + : RET_boost_mp_base { + typedef NT Type; + struct To_interval + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { + + std::pair operator()( const Type& x ) const { + return Boost_MP_internal::to_interval(x); + } + }; +}; + +template +struct RET_boost_mp > + : RET_boost_mp_base { + typedef NT Type; + struct To_interval + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { + + std::pair operator()( const Type& x ) const { + return Boost_MP_internal::to_interval( + boost::multiprecision::numerator(x), boost::multiprecision::denominator(x)); + } + }; +}; + +#ifdef CGAL_USE_MPFR +// Because of these full specializations, things get instantiated more eagerly. Make them artificially partial if necessary. +template <> +struct RET_boost_mp + : RET_boost_mp_base { + typedef boost::multiprecision::mpz_int Type; + struct To_interval + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { + std::pair + operator()(const Type& x) const { +#if MPFR_VERSION_MAJOR >= 3 + MPFR_DECL_INIT (y, 53); /* Assume IEEE-754 */ + int r = mpfr_set_z (y, x.backend().data(), MPFR_RNDA); + double i = mpfr_get_d (y, MPFR_RNDA); /* EXACT but can overflow */ + if (r == 0 && is_finite (i)) + return std::pair(i, i); + else + { + double s = nextafter (i, 0); + if (i < 0) + return std::pair(i, s); + else + return std::pair(s, i); + } +#else + mpfr_t y; + mpfr_init2 (y, 53); /* Assume IEEE-754 */ + mpfr_set_z (y, x.backend().data(), GMP_RNDD); + double i = mpfr_get_d (y, GMP_RNDD); /* EXACT but can overflow */ + mpfr_set_z (y, x.backend().data(), GMP_RNDU); + double s = mpfr_get_d (y, GMP_RNDU); /* EXACT but can overflow */ + mpfr_clear (y); + return std::pair(i, s); +#endif + } + }; +}; +template <> +struct RET_boost_mp + : RET_boost_mp_base { + typedef boost::multiprecision::mpq_rational Type; + struct To_interval + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { + std::pair + operator()(const Type& x) const { +# if MPFR_VERSION_MAJOR >= 3 + mpfr_exp_t emin = mpfr_get_emin(); + mpfr_set_emin(-1073); + MPFR_DECL_INIT (y, 53); /* Assume IEEE-754 */ + int r = mpfr_set_q (y, x.backend().data(), MPFR_RNDA); + r = mpfr_subnormalize (y, r, MPFR_RNDA); /* Round subnormals */ + double i = mpfr_get_d (y, MPFR_RNDA); /* EXACT but can overflow */ + mpfr_set_emin(emin); /* Restore old value, users may care */ + // With mpfr_set_emax(1024) we could drop the is_finite test + if (r == 0 && is_finite (i)) + return std::pair(i, i); + else + { + double s = nextafter (i, 0); + if (i < 0) + return std::pair(i, s); + else + return std::pair(s, i); + } +# else + mpfr_t y; + mpfr_init2 (y, 53); /* Assume IEEE-754 */ + mpfr_set_q (y, x.backend().data(), GMP_RNDD); + double i = mpfr_get_d (y, GMP_RNDD); /* EXACT but can overflow */ + mpfr_set_q (y, x.backend().data(), GMP_RNDU); + double s = mpfr_get_d (y, GMP_RNDU); /* EXACT but can overflow */ + mpfr_clear (y); + return std::pair(i, s); +# endif + } + }; +}; +#endif + +template +struct Real_embeddable_traits > +: RET_boost_mp > {}; +template +struct Real_embeddable_traits > +: Real_embeddable_traits::result_type > {}; + +// Modular_traits + +template ::value> > +struct MT_boost_mp { + typedef T NT; + typedef ::CGAL::Tag_false Is_modularizable; + typedef ::CGAL::Null_functor Residue_type; + typedef ::CGAL::Null_functor Modular_image; + typedef ::CGAL::Null_functor Modular_image_representative; +}; + +template +struct MT_boost_mp > { + typedef T NT; + typedef CGAL::Tag_true Is_modularizable; + typedef Residue Residue_type; + + struct Modular_image{ + Residue_type operator()(const NT& a){ + NT tmp(CGAL::mod(a,NT(Residue::get_current_prime()))); + return CGAL::Residue(tmp.template convert_to()); + } + }; + struct Modular_image_representative{ + NT operator()(const Residue_type& x){ + return NT(x.get_value()); + } + }; +}; + +template +struct Modular_traits > +: MT_boost_mp > {}; +template +struct Modular_traits > +: Modular_traits::result_type > {}; + +// Split_double + +template ::value> > +struct SD_boost_mp { + void operator()(double d, NT &num, NT &den) const + { + num = d; + den = 1; + } +}; + +template +struct SD_boost_mp > +{ + void operator()(double d, NT &num, NT &den) const + { + std::pair p = split_numerator_denominator(d); + num = NT(p.first); + den = NT(p.second); + } +}; + +template +struct Split_double > +: SD_boost_mp > {}; +template +struct Split_double > +: Split_double::result_type > {}; + + +// Fraction_traits + +template ::value> > +struct FT_boost_mp { + typedef T Type; + typedef Tag_false Is_fraction; + typedef Null_tag Numerator_type; + typedef Null_tag Denominator_type; + typedef Null_functor Common_factor; + typedef Null_functor Decompose; + typedef Null_functor Compose; +}; + +template +struct FT_boost_mp > { + typedef NT Type; + + typedef ::CGAL::Tag_true Is_fraction; + typedef typename boost::multiprecision::component_type::type Numerator_type; + typedef Numerator_type Denominator_type; + + typedef typename Algebraic_structure_traits< Numerator_type >::Gcd Common_factor; + + class Decompose { + public: + typedef Type first_argument_type; + typedef Numerator_type& second_argument_type; + typedef Denominator_type& third_argument_type; + void operator () ( + const Type& rat, + Numerator_type& num, + Denominator_type& den) { + num = numerator(rat); + den = denominator(rat); + } + }; + + class Compose { + public: + typedef Numerator_type first_argument_type; + typedef Denominator_type second_argument_type; + typedef Type result_type; + Type operator ()( + const Numerator_type& num , + const Denominator_type& den ) { + return Type(num, den); + } + }; +}; + +template +struct Fraction_traits > +: FT_boost_mp > {}; +template +struct Fraction_traits > +: Fraction_traits::result_type > {}; + + +// Coercions + +namespace internal { namespace boost_mp { BOOST_MPL_HAS_XXX_TRAIT_DEF(type) } } + +template +struct Coercion_traits, boost::multiprecision::number > +{ + typedef boost::common_type, boost::multiprecision::number > CT; + typedef Boolean_tag::value> Are_implicit_interoperable; + // FIXME: the implicit/explicit answers shouldn't be the same... + typedef Are_implicit_interoperable Are_explicit_interoperable; + // FIXME: won't compile when they are not interoperable. + typedef typename CT::type Type; + struct Cast{ + typedef Type result_type; + template + Type operator()(const U& x) const { + return Type(x); + } + }; +}; +// Avoid ambiguity with the specialization for ... +template +struct Coercion_traits, boost::multiprecision::number > +{ + typedef boost::multiprecision::number Type; + typedef Tag_true Are_implicit_interoperable; + typedef Tag_true Are_explicit_interoperable; + struct Cast{ + typedef Type result_type; + template + Type operator()(const U& x) const { + return Type(x); + } + }; +}; + +template +struct Coercion_traits < +boost::multiprecision::detail::expression, +boost::multiprecision::detail::expression > +: Coercion_traits < +typename boost::multiprecision::detail::expression::result_type, +typename boost::multiprecision::detail::expression::result_type> +{ }; +// Avoid ambiguity with the specialization for ... +template +struct Coercion_traits < +boost::multiprecision::detail::expression, +boost::multiprecision::detail::expression > +: Coercion_traits < +typename boost::multiprecision::detail::expression::result_type, +typename boost::multiprecision::detail::expression::result_type> +{ }; + +template +struct Coercion_traits, boost::multiprecision::detail::expression > +: Coercion_traits < +boost::multiprecision::number, +typename boost::multiprecision::detail::expression::result_type> +{ }; + +template +struct Coercion_traits, boost::multiprecision::number > +: Coercion_traits < +typename boost::multiprecision::detail::expression::result_type, +boost::multiprecision::number > +{ }; + +// TODO: fix existing coercions +// (double -> rational is implicit only for 1.56+, see ticket #10082) +// The real solution would be to avoid specializing Coercion_traits for all pairs of number types and let it auto-detect what works, so only broken types need an explicit specialization. + +// Ignore types smaller than long +#define CGAL_COERCE_INT(int) \ +template \ +struct Coercion_traits, int> { \ + typedef boost::multiprecision::number Type; \ + typedef Tag_true Are_implicit_interoperable; \ + typedef Tag_true Are_explicit_interoperable; \ + struct Cast{ \ + typedef Type result_type; \ + template Type operator()(const U& x) const { return Type(x); } \ + }; \ +}; \ +template \ +struct Coercion_traits > \ +: Coercion_traits, int> {}; \ +template \ +struct Coercion_traits, int> \ +: Coercion_traits::result_type, int>{}; \ +template \ +struct Coercion_traits > \ +: Coercion_traits::result_type, int>{} + +CGAL_COERCE_INT(short); +CGAL_COERCE_INT(int); +CGAL_COERCE_INT(long); +#undef CGAL_COERCE_INT + +// Ignore bounded-precision rationals +#define CGAL_COERCE_FLOAT(float) \ +template \ +struct Coercion_traits, float> { \ + typedef boost::multiprecision::number Type; \ + typedef Boolean_tag::value != boost::multiprecision::number_kind_integer> Are_implicit_interoperable; \ + typedef Are_implicit_interoperable Are_explicit_interoperable; \ + struct Cast{ \ + typedef Type result_type; \ + template Type operator()(const U& x) const { return Type(x); } \ + }; \ +}; \ +template \ +struct Coercion_traits > \ +: Coercion_traits, float> {}; \ +template \ +struct Coercion_traits, float> \ +: Coercion_traits::result_type, float>{}; \ +template \ +struct Coercion_traits > \ +: Coercion_traits::result_type, float>{} + +CGAL_COERCE_FLOAT(float); +CGAL_COERCE_FLOAT(double); +#undef CGAL_COERCE_FLOAT + +// Because of https://github.com/boostorg/multiprecision/issues/29 , this is not perfect and fails to read some KDS files. + +template <> +class Input_rep : public IO_rep_is_specialized { + boost::multiprecision::cpp_rational& q; +public: + Input_rep(boost::multiprecision::cpp_rational& qq) : q(qq) {} + std::istream& operator()(std::istream& in) const { + internal::read_float_or_quotient(in, q); + return in; + } +}; +#ifdef CGAL_USE_GMP +template <> +class Input_rep : public IO_rep_is_specialized { + boost::multiprecision::mpq_rational& q; +public: + Input_rep(boost::multiprecision::mpq_rational& qq) : q(qq) {} + std::istream& operator()(std::istream& in) const { + internal::read_float_or_quotient(in, q); + return in; + } +}; +#endif + +// Copied from leda_rational.h +namespace internal { + // See: Stream_support/include/CGAL/IO/io.h + template + void read_float_or_quotient(std::istream & is, ET& et); + + template <> + inline void read_float_or_quotient(std::istream & is, boost::multiprecision::cpp_rational& et) + { + internal::read_float_or_quotient(is, et); + } +#ifdef CGAL_USE_GMP + template <> + inline void read_float_or_quotient(std::istream & is, boost::multiprecision::mpq_rational& et) + { + internal::read_float_or_quotient(is, et); + } +#endif +} // namespace internal + +#ifdef CGAL_USE_BOOST_MP + +template< > class Real_embeddable_traits< Quotient > + : public INTERN_QUOTIENT::Real_embeddable_traits_quotient_base< Quotient > { + + public: + typedef Quotient Type; + + class To_interval + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { + public: + std::pair operator()( const Type& x ) const { + return Boost_MP_internal::to_interval(x.num, x.den); + } + }; +}; + +#endif // CGAL_USE_BOOST_MP + +} //namespace CGAL + +namespace Eigen { + template struct NumTraits; + template<> struct NumTraits + { + typedef boost::multiprecision::cpp_int Real; + typedef boost::multiprecision::cpp_rational NonInteger; + typedef boost::multiprecision::cpp_int Nested; + typedef boost::multiprecision::cpp_int Literal; + + static inline Real epsilon() { return 0; } + static inline Real dummy_precision() { return 0; } + + enum { + IsInteger = 1, + IsSigned = 1, + IsComplex = 0, + RequireInitialization = 1, + ReadCost = 6, + AddCost = 30, + MulCost = 50 + }; + }; + + template<> struct NumTraits + { + typedef boost::multiprecision::cpp_rational Real; + typedef boost::multiprecision::cpp_rational NonInteger; + typedef boost::multiprecision::cpp_rational Nested; + typedef boost::multiprecision::cpp_rational Literal; + + static inline Real epsilon() { return 0; } + static inline Real dummy_precision() { return 0; } + + enum { + IsInteger = 0, + IsSigned = 1, + IsComplex = 0, + RequireInitialization = 1, + ReadCost = 6, + AddCost = 150, + MulCost = 100 + }; + }; + +#ifdef CGAL_USE_GMP + + template<> struct NumTraits + { + typedef boost::multiprecision::mpz_int Real; + typedef boost::multiprecision::mpq_rational NonInteger; + typedef boost::multiprecision::mpz_int Nested; + typedef boost::multiprecision::mpz_int Literal; + + static inline Real epsilon() { return 0; } + static inline Real dummy_precision() { return 0; } + + enum { + IsInteger = 1, + IsSigned = 1, + IsComplex = 0, + RequireInitialization = 1, + ReadCost = 6, + AddCost = 30, + MulCost = 50 + }; + }; + + template<> struct NumTraits + { + typedef boost::multiprecision::mpq_rational Real; + typedef boost::multiprecision::mpq_rational NonInteger; + typedef boost::multiprecision::mpq_rational Nested; + typedef boost::multiprecision::mpq_rational Literal; + + static inline Real epsilon() { return 0; } + static inline Real dummy_precision() { return 0; } + + enum { + IsInteger = 0, + IsSigned = 1, + IsComplex = 0, + RequireInitialization = 1, + ReadCost = 6, + AddCost = 150, + MulCost = 100 + }; + }; +#endif // CGAL_USE_GMP + + +} // namespace Eigen + +#endif // BOOST_VERSION +#endif diff --git a/Number_types/test/Number_types/CMakeLists.txt b/Number_types/test/Number_types/CMakeLists.txt index b3dd989c7664..73488a8a819b 100644 --- a/Number_types/test/Number_types/CMakeLists.txt +++ b/Number_types/test/Number_types/CMakeLists.txt @@ -13,10 +13,6 @@ include_directories(BEFORE include) create_single_source_cgal_program("bench_interval.cpp") create_single_source_cgal_program("cpp_float.cpp") create_single_source_cgal_program("constant.cpp") -create_single_source_cgal_program("CORE_BigFloat.cpp") -create_single_source_cgal_program("CORE_BigInt.cpp") -create_single_source_cgal_program("CORE_BigRat.cpp") -create_single_source_cgal_program("CORE_Expr.cpp") create_single_source_cgal_program("Counted_number.cpp") create_single_source_cgal_program("double.cpp") create_single_source_cgal_program("doubletst.cpp") @@ -66,14 +62,17 @@ create_single_source_cgal_program("utilities.cpp") create_single_source_cgal_program("Exact_rational.cpp") create_single_source_cgal_program("Mpzf_new.cpp") -find_package( GMP ) -if( GMP_FOUND AND NOT CGAL_DISABLE_GMP ) +if( CGAL_Core_FOUND ) create_single_source_cgal_program( "CORE_Expr_ticket_4296.cpp" ) + create_single_source_cgal_program("CORE_BigFloat.cpp") + create_single_source_cgal_program("CORE_BigInt.cpp") + create_single_source_cgal_program("CORE_BigRat.cpp") + create_single_source_cgal_program("CORE_Expr.cpp") find_package(MPFI QUIET) if( MPFI_FOUND ) include( ${MPFI_USE_FILE} ) endif() #MPFI_FOUND -endif() #GMP_FOUND AND NOT CGAL_DISABLE_GMP +endif() #CGAL_Core_FOUND if(NOT CGAL_DISABLE_GMP) create_single_source_cgal_program( "Gmpfi.cpp" ) diff --git a/Number_types/test/Number_types/CORE_BigInt.cpp b/Number_types/test/Number_types/CORE_BigInt.cpp index 8cfe816f0439..79b207d2d87e 100644 --- a/Number_types/test/Number_types/CORE_BigInt.cpp +++ b/Number_types/test/Number_types/CORE_BigInt.cpp @@ -72,4 +72,3 @@ int main() { return 0; } #endif // CGAL_USE_CORE //EOF - diff --git a/Number_types/test/Number_types/CORE_BigRat.cpp b/Number_types/test/Number_types/CORE_BigRat.cpp index cb3f1f199c7b..566bc8c5358a 100644 --- a/Number_types/test/Number_types/CORE_BigRat.cpp +++ b/Number_types/test/Number_types/CORE_BigRat.cpp @@ -19,24 +19,25 @@ void test_io(){ std::stringstream ss; CGAL::IO::set_ascii_mode(ss); ss << CGAL::IO::oformat(NT(1)); - //std::cout << ss.str()< #include -#include +#include #include #include @@ -119,7 +119,7 @@ void test_MSB_bug() int main() { precision_bug(); test_istream(); - test_MSB_bug(); + test_MSB_bug(); test_MSB_bug(); typedef CORE::Expr NT; diff --git a/Number_types/test/Number_types/ioformat.cpp b/Number_types/test/Number_types/ioformat.cpp index 54eaa26bf227..457f1be15b11 100644 --- a/Number_types/test/Number_types/ioformat.cpp +++ b/Number_types/test/Number_types/ioformat.cpp @@ -106,7 +106,6 @@ int main() // CORE #ifdef CGAL_USE_CORE - static_assert(CGAL::Output_rep::is_specialized == true); //bug in io for CORE. test_it("CORE::BigInt"); test_it("CORE::BigRat"); diff --git a/Number_types/test/Number_types/test_eigen.cpp b/Number_types/test/Number_types/test_eigen.cpp index 8e0dd9bf1947..02151b80ec08 100644 --- a/Number_types/test/Number_types/test_eigen.cpp +++ b/Number_types/test/Number_types/test_eigen.cpp @@ -24,6 +24,8 @@ #ifdef CGAL_EIGEN3_ENABLED #include + + // Just check that it all compiles. template void check_(){ @@ -33,7 +35,7 @@ void check_(){ Eigen::Matrix v(3); v << 1, 2, 3; NT t=v.dot(v); - v+=d*m*(t*v); + v+=d*Eigen::Matrix(m*(t*v)); std::ptrdiff_t si=v.size(); CGAL_USE(si); } diff --git a/Number_types/test/Number_types/utilities.cpp b/Number_types/test/Number_types/utilities.cpp index 48400c975205..e716624ffaed 100644 --- a/Number_types/test/Number_types/utilities.cpp +++ b/Number_types/test/Number_types/utilities.cpp @@ -5,7 +5,10 @@ #include #include #include + +#ifdef CGAL_USE_BOOST_MP #include +#endif #ifdef CGAL_USE_GMP #include diff --git a/Optimal_bounding_box/package_info/Optimal_bounding_box/dependencies b/Optimal_bounding_box/package_info/Optimal_bounding_box/dependencies index 249760e29284..37cb6893ab85 100644 --- a/Optimal_bounding_box/package_info/Optimal_bounding_box/dependencies +++ b/Optimal_bounding_box/package_info/Optimal_bounding_box/dependencies @@ -2,6 +2,7 @@ Algebraic_foundations Arithmetic_kernel BGL Bounding_volumes +CGAL_Core Cartesian_kernel Circulator Convex_hull_2 diff --git a/Partition_2/package_info/Partition_2/dependencies b/Partition_2/package_info/Partition_2/dependencies index 0d4ee19ad2b1..2d383a64c885 100644 --- a/Partition_2/package_info/Partition_2/dependencies +++ b/Partition_2/package_info/Partition_2/dependencies @@ -1,5 +1,6 @@ Algebraic_foundations Arithmetic_kernel +CGAL_Core Cartesian_kernel Circulator Convex_hull_2 diff --git a/Periodic_3_mesh_3/package_info/Periodic_3_mesh_3/dependencies b/Periodic_3_mesh_3/package_info/Periodic_3_mesh_3/dependencies index eb2b8e24cc3a..bd1fc7bd057f 100644 --- a/Periodic_3_mesh_3/package_info/Periodic_3_mesh_3/dependencies +++ b/Periodic_3_mesh_3/package_info/Periodic_3_mesh_3/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Arithmetic_kernel BGL +CGAL_Core Cartesian_kernel Circulator Convex_hull_2 diff --git a/Periodic_3_triangulation_3/package_info/Periodic_3_triangulation_3/dependencies b/Periodic_3_triangulation_3/package_info/Periodic_3_triangulation_3/dependencies index b31b936ff044..619cafd06060 100644 --- a/Periodic_3_triangulation_3/package_info/Periodic_3_triangulation_3/dependencies +++ b/Periodic_3_triangulation_3/package_info/Periodic_3_triangulation_3/dependencies @@ -1,5 +1,6 @@ Algebraic_foundations Arithmetic_kernel +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Point_set_processing_3/package_info/Point_set_processing_3/dependencies b/Point_set_processing_3/package_info/Point_set_processing_3/dependencies index dcdadf3e8dcc..3d33ad32a3e6 100644 --- a/Point_set_processing_3/package_info/Point_set_processing_3/dependencies +++ b/Point_set_processing_3/package_info/Point_set_processing_3/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Arithmetic_kernel BGL +CGAL_Core Cartesian_kernel Circulator Convex_hull_2 diff --git a/Poisson_surface_reconstruction_3/package_info/Poisson_surface_reconstruction_3/dependencies b/Poisson_surface_reconstruction_3/package_info/Poisson_surface_reconstruction_3/dependencies index 5c532a3d624e..e8a4a934cd68 100644 --- a/Poisson_surface_reconstruction_3/package_info/Poisson_surface_reconstruction_3/dependencies +++ b/Poisson_surface_reconstruction_3/package_info/Poisson_surface_reconstruction_3/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Arithmetic_kernel BGL +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Polygon_mesh_processing/package_info/Polygon_mesh_processing/dependencies b/Polygon_mesh_processing/package_info/Polygon_mesh_processing/dependencies index 6d471658093c..f44718e3c9bc 100644 --- a/Polygon_mesh_processing/package_info/Polygon_mesh_processing/dependencies +++ b/Polygon_mesh_processing/package_info/Polygon_mesh_processing/dependencies @@ -3,6 +3,7 @@ Algebraic_foundations Arithmetic_kernel BGL Box_intersection_d +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Polygonal_surface_reconstruction/package_info/Polygonal_surface_reconstruction/dependencies b/Polygonal_surface_reconstruction/package_info/Polygonal_surface_reconstruction/dependencies index 650e4a65343e..dfaa76af3a57 100644 --- a/Polygonal_surface_reconstruction/package_info/Polygonal_surface_reconstruction/dependencies +++ b/Polygonal_surface_reconstruction/package_info/Polygonal_surface_reconstruction/dependencies @@ -2,6 +2,7 @@ Algebraic_foundations Alpha_shapes_2 Arithmetic_kernel BGL +CGAL_Core Cartesian_kernel Circulator Convex_hull_2 @@ -21,8 +22,8 @@ Number_types Point_set_3 Point_set_processing_3 Polygon -Polygonal_surface_reconstruction Polygon_mesh_processing +Polygonal_surface_reconstruction Principal_component_analysis Principal_component_analysis_LGPL Profiling_tools diff --git a/Polyline_simplification_2/package_info/Polyline_simplification_2/dependencies b/Polyline_simplification_2/package_info/Polyline_simplification_2/dependencies index 46b60927a441..b1e47ef32221 100644 --- a/Polyline_simplification_2/package_info/Polyline_simplification_2/dependencies +++ b/Polyline_simplification_2/package_info/Polyline_simplification_2/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Arithmetic_kernel BGL +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Polynomial/test/Polynomial/test_polynomial.h b/Polynomial/test/Polynomial/test_polynomial.h index c1943d96ae94..1b5bb0868aca 100644 --- a/Polynomial/test/Polynomial/test_polynomial.h +++ b/Polynomial/test/Polynomial/test_polynomial.h @@ -307,7 +307,6 @@ void io() { std::ostringstream os; CGAL::IO::set_pretty_mode(os); os << CGAL::IO::oformat(POLY(NT(3))); - //std::cout < #include +#ifdef CGAL_USE_BOOST_MP #include +#endif //Currently already included in boost_mp.h //#ifdef CGAL_USE_BOOST_MP //# include diff --git a/SMDS_3/package_info/SMDS_3/dependencies b/SMDS_3/package_info/SMDS_3/dependencies index bebf22165bb0..749f4764b554 100644 --- a/SMDS_3/package_info/SMDS_3/dependencies +++ b/SMDS_3/package_info/SMDS_3/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Arithmetic_kernel BGL +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Scale_space_reconstruction_3/package_info/Scale_space_reconstruction_3/dependencies b/Scale_space_reconstruction_3/package_info/Scale_space_reconstruction_3/dependencies index 114d4ba5acdb..4582cf68fe68 100644 --- a/Scale_space_reconstruction_3/package_info/Scale_space_reconstruction_3/dependencies +++ b/Scale_space_reconstruction_3/package_info/Scale_space_reconstruction_3/dependencies @@ -3,6 +3,7 @@ Algebraic_foundations Alpha_shapes_3 Arithmetic_kernel BGL +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Segment_Delaunay_graph_2/package_info/Segment_Delaunay_graph_2/dependencies b/Segment_Delaunay_graph_2/package_info/Segment_Delaunay_graph_2/dependencies index c3083729fefd..62981bc0f230 100644 --- a/Segment_Delaunay_graph_2/package_info/Segment_Delaunay_graph_2/dependencies +++ b/Segment_Delaunay_graph_2/package_info/Segment_Delaunay_graph_2/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Apollonius_graph_2 Arithmetic_kernel +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Segment_Delaunay_graph_Linf_2/package_info/Segment_Delaunay_graph_Linf_2/dependencies b/Segment_Delaunay_graph_Linf_2/package_info/Segment_Delaunay_graph_Linf_2/dependencies index 783d3ee4cb25..d680be9c38d5 100644 --- a/Segment_Delaunay_graph_Linf_2/package_info/Segment_Delaunay_graph_Linf_2/dependencies +++ b/Segment_Delaunay_graph_Linf_2/package_info/Segment_Delaunay_graph_Linf_2/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Apollonius_graph_2 Arithmetic_kernel +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Shape_detection/package_info/Shape_detection/dependencies b/Shape_detection/package_info/Shape_detection/dependencies index 7758a93501ea..23bbe655dfaf 100644 --- a/Shape_detection/package_info/Shape_detection/dependencies +++ b/Shape_detection/package_info/Shape_detection/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Arithmetic_kernel BGL +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Skin_surface_3/package_info/Skin_surface_3/dependencies b/Skin_surface_3/package_info/Skin_surface_3/dependencies index fb635c6334cc..e04beb03945c 100644 --- a/Skin_surface_3/package_info/Skin_surface_3/dependencies +++ b/Skin_surface_3/package_info/Skin_surface_3/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Arithmetic_kernel BGL +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Snap_rounding_2/package_info/Snap_rounding_2/dependencies b/Snap_rounding_2/package_info/Snap_rounding_2/dependencies index 2d53f573e0d6..9b654c5c0ccd 100644 --- a/Snap_rounding_2/package_info/Snap_rounding_2/dependencies +++ b/Snap_rounding_2/package_info/Snap_rounding_2/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Arithmetic_kernel Arrangement_on_surface_2 +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Surface_mesh_parameterization/package_info/Surface_mesh_parameterization/dependencies b/Surface_mesh_parameterization/package_info/Surface_mesh_parameterization/dependencies index 19c7b2f79832..8acc07edef06 100644 --- a/Surface_mesh_parameterization/package_info/Surface_mesh_parameterization/dependencies +++ b/Surface_mesh_parameterization/package_info/Surface_mesh_parameterization/dependencies @@ -2,6 +2,7 @@ Algebraic_foundations Arithmetic_kernel BGL Box_intersection_d +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Surface_mesh_skeletonization/package_info/Surface_mesh_skeletonization/dependencies b/Surface_mesh_skeletonization/package_info/Surface_mesh_skeletonization/dependencies index 93a216163663..cea4bd48a905 100644 --- a/Surface_mesh_skeletonization/package_info/Surface_mesh_skeletonization/dependencies +++ b/Surface_mesh_skeletonization/package_info/Surface_mesh_skeletonization/dependencies @@ -2,6 +2,7 @@ AABB_tree Algebraic_foundations Arithmetic_kernel BGL +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Surface_mesh_topology/package_info/Surface_mesh_topology/dependencies b/Surface_mesh_topology/package_info/Surface_mesh_topology/dependencies index dc2f511d1b24..91f6a41ad104 100644 --- a/Surface_mesh_topology/package_info/Surface_mesh_topology/dependencies +++ b/Surface_mesh_topology/package_info/Surface_mesh_topology/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Arithmetic_kernel BGL +CGAL_Core Cartesian_kernel Circulator Combinatorial_map diff --git a/Surface_mesher/package_info/Surface_mesher/dependencies b/Surface_mesher/package_info/Surface_mesher/dependencies index e6e8a3909664..bfe6c4d3548e 100644 --- a/Surface_mesher/package_info/Surface_mesher/dependencies +++ b/Surface_mesher/package_info/Surface_mesher/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Arithmetic_kernel BGL +CGAL_Core CGAL_ImageIO Cartesian_kernel Circulator diff --git a/Surface_sweep_2/package_info/Surface_sweep_2/dependencies b/Surface_sweep_2/package_info/Surface_sweep_2/dependencies index 09546686abf3..1a04d474a621 100644 --- a/Surface_sweep_2/package_info/Surface_sweep_2/dependencies +++ b/Surface_sweep_2/package_info/Surface_sweep_2/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Arithmetic_kernel Arrangement_on_surface_2 +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Tetrahedral_remeshing/package_info/Tetrahedral_remeshing/dependencies b/Tetrahedral_remeshing/package_info/Tetrahedral_remeshing/dependencies index d9c5098d64f6..f9c578d62a23 100644 --- a/Tetrahedral_remeshing/package_info/Tetrahedral_remeshing/dependencies +++ b/Tetrahedral_remeshing/package_info/Tetrahedral_remeshing/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Arithmetic_kernel BGL +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Triangulation_2/package_info/Triangulation_2/dependencies b/Triangulation_2/package_info/Triangulation_2/dependencies index c8d90b721ca3..e5682c455234 100644 --- a/Triangulation_2/package_info/Triangulation_2/dependencies +++ b/Triangulation_2/package_info/Triangulation_2/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Arithmetic_kernel BGL +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Triangulation_3/package_info/Triangulation_3/dependencies b/Triangulation_3/package_info/Triangulation_3/dependencies index a68982ddaa59..15e6860497ea 100644 --- a/Triangulation_3/package_info/Triangulation_3/dependencies +++ b/Triangulation_3/package_info/Triangulation_3/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Arithmetic_kernel BGL +CGAL_Core Cartesian_kernel Circulator Distance_2 diff --git a/Triangulation_on_sphere_2/package_info/Triangulation_on_sphere_2/dependencies b/Triangulation_on_sphere_2/package_info/Triangulation_on_sphere_2/dependencies index 5b77a741e4d0..bf3594adb9b4 100644 --- a/Triangulation_on_sphere_2/package_info/Triangulation_on_sphere_2/dependencies +++ b/Triangulation_on_sphere_2/package_info/Triangulation_on_sphere_2/dependencies @@ -2,6 +2,7 @@ Algebraic_foundations Algebraic_kernel_for_spheres Arithmetic_kernel BGL +CGAL_Core Cartesian_kernel Circular_kernel_3 Circulator diff --git a/Visibility_2/package_info/Visibility_2/dependencies b/Visibility_2/package_info/Visibility_2/dependencies index e8367c224170..2199ba4f76d3 100644 --- a/Visibility_2/package_info/Visibility_2/dependencies +++ b/Visibility_2/package_info/Visibility_2/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations Arithmetic_kernel Arrangement_on_surface_2 +CGAL_Core Cartesian_kernel Circulator Distance_2