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 04d76854482..fd00508d662 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 @@ -50,28 +50,57 @@ class Expr; namespace CGAL { namespace internal { // Two classes which tell the preferred "exact number types" corresponding to a type. +// Exact_ring_selector and Exact_field_selector are used by EPICK as exact number type +// to answer predicates at the end of the filtering chain of predicates and EPECK uses +// Exact_field_selector for as its exact number type. -// The default template chooses mpq_class, Gmpq, leda_rational, or Quotient. -// It should support the built-in types. -template < typename > -struct Exact_field_selector -#if BOOST_VERSION > 107900 && defined(CGAL_USE_BOOST_MP) -// use boost-mp by default -// Boost -{ typedef BOOST_cpp_arithmetic_kernel::Rational Type; }; -#else // BOOST_VERSION > 107900 -#ifdef CGAL_USE_GMPXX -{ typedef mpq_class Type; }; -#elif defined(CGAL_USE_GMP) -#if defined(CGAL_USE_BOOST_MP) -{ typedef BOOST_gmp_arithmetic_kernel::Rational Type; }; +enum ENT_backend_choice +{ + GMP_BACKEND, + GMPXX_BACKEND, + BOOST_GMP_BACKEND, + BOOST_BACKEND, + LEDA_BACKEND, + MP_FLOAT_BACKEND +}; + +template +struct Exact_NT_backend; + +#ifdef CGAL_USE_GMP +template <> +struct Exact_NT_backend +{ + typedef Gmpq Rational; +#ifdef CGAL_HAS_MPZF + typedef Mpzf Integer; #else -{ typedef Gmpq Type; }; + typedef Gmpzf Integer; #endif -#elif defined(CGAL_USE_LEDA) -{ typedef leda_rational Type; }; -#elif defined(CGAL_USE_BOOST_MP) +}; +#endif + +#ifdef CGAL_USE_GMPXX +template <> +struct Exact_NT_backend +{ + typedef mpq_class Rational; + typedef Exact_NT_backend::Integer Integer; +}; +#endif + +#ifdef CGAL_USE_BOOST_MP +template <> +struct Exact_NT_backend +{ + typedef BOOST_gmp_arithmetic_kernel::Rational Rational; + typedef Exact_NT_backend::Integer Integer; +}; + +template <> +struct Exact_NT_backend +{ // See the discussion in https://github.com/CGAL/cgal/pull/3614 // This is disabled for now because cpp_rational is even slower than Quotient. Quotient will be a good candidate after some polishing. // In fact, the new version of cpp_rational from here: https://github.com/boostorg/multiprecision/pull/366 @@ -79,32 +108,64 @@ struct Exact_field_selector // while Quotient does not. Though, we can still use it if needed. #if BOOST_VERSION <= 107800 // See this comment: https://github.com/CGAL/cgal/pull/5937#discussion_r721533675 -{ typedef Quotient Type; }; + typedef Quotient Rational; #else -{ typedef BOOST_cpp_arithmetic_kernel::Rational Type; }; + typedef BOOST_cpp_arithmetic_kernel::Rational Rational; #endif -#else -{ typedef Quotient Type; }; + typedef cpp_float Integer; +}; #endif + +#ifdef CGAL_USE_LEDA +template <> +struct Exact_NT_backend +{ + typedef leda_rational Rational; + typedef leda_integer Integer; +}; +#endif + +template <> +struct Exact_NT_backend +{ + typedef Quotient Rational; + typedef MP_Float Integer; +}; + +constexpr ENT_backend_choice Default_Exact_nt_back_end = +#if BOOST_VERSION > 107900 && defined(CGAL_USE_BOOST_MP) + BOOST_BACKEND; +#else // BOOST_VERSION > 107900 + #ifdef CGAL_USE_GMPXX + GMPXX_BACKEND; + #elif defined(CGAL_USE_GMP) + #if defined(CGAL_USE_BOOST_MP) + BOOST_GMP_BACKEND; + #else + GMP_BACKEND; + #endif + #elif defined(CGAL_USE_LEDA) + LEDA_BACKEND; + #else + MP_FLOAT_BACKEND; + #endif #endif // BOOST_VERSION > 107900 +template < typename > +struct Exact_field_selector +{ + using Type = typename Exact_NT_backend::Rational; +}; + // By default, a field is a safe choice of ring. template < typename T > struct Exact_ring_selector : Exact_field_selector < T > { }; template <> struct Exact_ring_selector -#if BOOST_VERSION > 107900 && defined(CGAL_USE_BOOST_MP) -{ typedef cpp_float Type; }; -#elif CGAL_HAS_MPZF -{ typedef Mpzf Type; }; - #elif defined(CGAL_USE_BOOST_MP) -{ typedef boost::multiprecision::cpp_int Type; }; -#elif defined(CGAL_HAS_THREADS) || !defined(CGAL_USE_GMP) -{ typedef MP_Float Type; }; -#else -{ typedef Gmpzf Type; }; -#endif +{ + using Type = typename Exact_NT_backend::Integer; +}; template <> struct Exact_ring_selector : Exact_ring_selector { };