diff --git a/Arithmetic_kernel/include/CGAL/BOOST_MP_arithmetic_kernel.h b/Arithmetic_kernel/include/CGAL/BOOST_MP_arithmetic_kernel.h new file mode 100644 index 00000000000..101ee85e4c4 --- /dev/null +++ b/Arithmetic_kernel/include/CGAL/BOOST_MP_arithmetic_kernel.h @@ -0,0 +1,45 @@ +// Copyright (c) 2017 Inria. +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Author: Marc Glisse + +#ifndef CGAL_GMPXX_ARITHMETIC_KERNEL_H +#define CGAL_GMPXX_ARITHMETIC_KERNEL_H + +#include +#include + +#include + +// 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 + */ +struct BOOST_MP_arithmetic_kernel : internal::Arithmetic_kernel_base { + typedef boost::multiprecision::cpp_int Integer; + typedef boost::multiprecision::cpp_rational Rational; +}; + +template +struct Get_arithmetic_kernel > { + typedef BOOST_MP_arithmetic_kernel Arithmetic_kernel; +}; +template +struct Get_arithmetic_kernel > { + typedef BOOST_MP_arithmetic_kernel Arithmetic_kernel; +}; +} //namespace CGAL +#endif diff --git a/Number_types/include/CGAL/boost_mp.h b/Number_types/include/CGAL/boost_mp.h index a0dcabffc08..9b92356d472 100644 --- a/Number_types/include/CGAL/boost_mp.h +++ b/Number_types/include/CGAL/boost_mp.h @@ -359,6 +359,21 @@ struct Coercion_traits, boost::multiprecis } }; }; +// 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 < @@ -368,6 +383,15 @@ boost::multiprecision::detail::expression > 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 > @@ -383,10 +407,55 @@ typename boost::multiprecision::detail::expression::result_type, boost::multiprecision::number > { }; -// TODO: coercion with int, long, double... +// TODO: coercion with expressions, 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> {} + +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> {} + +CGAL_COERCE_FLOAT(float); +CGAL_COERCE_FLOAT(double); +#undef CGAL_COERCE_FLOAT + } //namespace CGAL +#include + #endif // BOOST_VERSION #endif