From 8aa87ffde78f2c8d4d8e8419e5362f71240e3ac2 Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Fri, 12 Jun 2026 14:36:16 -0400 Subject: [PATCH 01/10] Use templates for get_from_BigReal Ring types that cannot be set from a BigReal no longer need to define a boilerplate set_from_BigReal returning false; get_from_BigReal uses SFINAE to detect whether the member exists and falls back to false otherwise. Co-Authored-By: Claude Sonnet 4.6 --- .../e/basic-rings/aring-GF-flint-big.hpp | 7 -- M2/Macaulay2/e/basic-rings/aring-GF-flint.hpp | 7 -- M2/Macaulay2/e/basic-rings/aring-QQ-flint.hpp | 7 -- M2/Macaulay2/e/basic-rings/aring-ZZ-flint.hpp | 7 -- .../e/basic-rings/aring-ZZp-ffpack.hpp | 7 -- .../e/basic-rings/aring-ZZp-flint.hpp | 7 -- M2/Macaulay2/e/basic-rings/aring-ZZp.hpp | 7 -- M2/Macaulay2/e/basic-rings/aring-m2-GF.hpp | 7 -- M2/Macaulay2/e/basic-rings/aring-tower.hpp | 7 -- .../e/basic-rings/aring-translate.hpp | 73 +++++-------------- M2/Macaulay2/e/basic-rings/aring.hpp | 6 -- 11 files changed, 20 insertions(+), 122 deletions(-) diff --git a/M2/Macaulay2/e/basic-rings/aring-GF-flint-big.hpp b/M2/Macaulay2/e/basic-rings/aring-GF-flint-big.hpp index 7a4a95a904d..77ebdd41840 100644 --- a/M2/Macaulay2/e/basic-rings/aring-GF-flint-big.hpp +++ b/M2/Macaulay2/e/basic-rings/aring-GF-flint-big.hpp @@ -226,13 +226,6 @@ class ARingGFFlintBig : public RingInterface return true; } - bool set_from_BigReal(ElementType& result, gmp_RR a) const - { - (void) result; - (void) a; - return false; - } - void negate(ElementType& result, const ElementType& a) const { fq_nmod_neg(&result, &a, mContext); diff --git a/M2/Macaulay2/e/basic-rings/aring-GF-flint.hpp b/M2/Macaulay2/e/basic-rings/aring-GF-flint.hpp index 4dc400099f9..081dd902075 100644 --- a/M2/Macaulay2/e/basic-rings/aring-GF-flint.hpp +++ b/M2/Macaulay2/e/basic-rings/aring-GF-flint.hpp @@ -207,13 +207,6 @@ class ARingGFFlint : public RingInterface return true; } - bool set_from_BigReal(ElementType& result, gmp_RR a) const - { - (void) result; - (void) a; - return false; - } - void negate(ElementType& result, const ElementType& a) const { fq_zech_neg(&result, &a, mContext); diff --git a/M2/Macaulay2/e/basic-rings/aring-QQ-flint.hpp b/M2/Macaulay2/e/basic-rings/aring-QQ-flint.hpp index 8a86241b3ed..d39be513537 100644 --- a/M2/Macaulay2/e/basic-rings/aring-QQ-flint.hpp +++ b/M2/Macaulay2/e/basic-rings/aring-QQ-flint.hpp @@ -116,13 +116,6 @@ class ARingQQFlint : public SimpleARing return true; } - bool set_from_BigReal(ElementType& result, gmp_RR a) const - { - (void) result; - (void) a; - return false; - } - void set_var(ElementType& result, int v) const { (void) v; diff --git a/M2/Macaulay2/e/basic-rings/aring-ZZ-flint.hpp b/M2/Macaulay2/e/basic-rings/aring-ZZ-flint.hpp index 36849a01dca..1e64612232a 100644 --- a/M2/Macaulay2/e/basic-rings/aring-ZZ-flint.hpp +++ b/M2/Macaulay2/e/basic-rings/aring-ZZ-flint.hpp @@ -111,13 +111,6 @@ void set_from_mpz(ElementType& result, mpz_srcptr a) const return false; } - bool set_from_BigReal(ElementType& result, gmp_RR a) const - { - (void) result; - (void) a; - return false; - } - void set_var(ElementType& result, int v) const { (void) v; diff --git a/M2/Macaulay2/e/basic-rings/aring-ZZp-ffpack.hpp b/M2/Macaulay2/e/basic-rings/aring-ZZp-ffpack.hpp index 435480bac5f..a608f5b9da4 100644 --- a/M2/Macaulay2/e/basic-rings/aring-ZZp-ffpack.hpp +++ b/M2/Macaulay2/e/basic-rings/aring-ZZp-ffpack.hpp @@ -160,13 +160,6 @@ class ARingZZpFFPACK : public SimpleARing bool set_from_mpq(ElementType &result, mpq_srcptr a) const; - bool set_from_BigReal(ElementType &result, gmp_RR a) const - { - (void) result; - (void) a; - return false; - } - ElementType computeGenerator() const; void set_var(ElementType &result, int v) const diff --git a/M2/Macaulay2/e/basic-rings/aring-ZZp-flint.hpp b/M2/Macaulay2/e/basic-rings/aring-ZZp-flint.hpp index 44a2278a7f4..3f8097fa1f0 100644 --- a/M2/Macaulay2/e/basic-rings/aring-ZZp-flint.hpp +++ b/M2/Macaulay2/e/basic-rings/aring-ZZp-flint.hpp @@ -119,13 +119,6 @@ class ARingZZpFlint : public SimpleARing return true; } - bool set_from_BigReal(ElementType &result, gmp_RR a) const - { - (void) result; - (void) a; - return false; - } - // arithmetic void negate(ElementType &result, ElementType a) const { diff --git a/M2/Macaulay2/e/basic-rings/aring-ZZp.hpp b/M2/Macaulay2/e/basic-rings/aring-ZZp.hpp index 014b1f89f98..177acba081d 100644 --- a/M2/Macaulay2/e/basic-rings/aring-ZZp.hpp +++ b/M2/Macaulay2/e/basic-rings/aring-ZZp.hpp @@ -141,13 +141,6 @@ class ARingZZp : public SimpleARing return true; } - bool set_from_BigReal(elem &result, gmp_RR a) const - { - (void) result; - (void) a; - return false; - } - // arithmetic void negate(elem &result, elem a) const { diff --git a/M2/Macaulay2/e/basic-rings/aring-m2-GF.hpp b/M2/Macaulay2/e/basic-rings/aring-m2-GF.hpp index ece986c1b50..f5a1726e4ea 100644 --- a/M2/Macaulay2/e/basic-rings/aring-m2-GF.hpp +++ b/M2/Macaulay2/e/basic-rings/aring-m2-GF.hpp @@ -186,13 +186,6 @@ class ARingGFM2 : public SimpleARing return true; } - bool set_from_BigReal(elem &result, gmp_RR a) const - { - (void) result; - (void) a; - return false; - } - void negate(elem &result, elem a) const { if (a != 0) diff --git a/M2/Macaulay2/e/basic-rings/aring-tower.hpp b/M2/Macaulay2/e/basic-rings/aring-tower.hpp index d9215f8519c..61bdc119502 100644 --- a/M2/Macaulay2/e/basic-rings/aring-tower.hpp +++ b/M2/Macaulay2/e/basic-rings/aring-tower.hpp @@ -227,13 +227,6 @@ class ARingTower : public RingInterface return false; } // TODO: write this - bool set_from_BigReal(elem &result, gmp_RR a) const - { - (void) result; - (void) a; - return false; - } - // arithmetic void negate(elem &result, elem a) const { diff --git a/M2/Macaulay2/e/basic-rings/aring-translate.hpp b/M2/Macaulay2/e/basic-rings/aring-translate.hpp index c46bcf9e575..a247b30b24d 100644 --- a/M2/Macaulay2/e/basic-rings/aring-translate.hpp +++ b/M2/Macaulay2/e/basic-rings/aring-translate.hpp @@ -3,6 +3,9 @@ #ifndef M2_BASIC_RINGS_ARING_TRANSLATE_HPP_ #define M2_BASIC_RINGS_ARING_TRANSLATE_HPP_ +#include +#include + /////////////////////////////////////////////////////// // Contains functions which are "ring translational" // /////////////////////////////////////////////////////// @@ -27,13 +30,26 @@ #include "basic-rings/aring-GF-flint.hpp" namespace M2 { + +namespace detail { +template +inline constexpr bool has_set_from_BigReal = false; + +template +inline constexpr bool has_set_from_BigReal< + RT, + std::void_t().set_from_BigReal( + std::declval(), std::declval()))>> = + true; +} // namespace detail + template bool get_from_BigReal(const RT& R, typename RT::ElementType& a, gmp_RR b) { - (void) R; - (void) a; - (void) b; - return false; + if constexpr (detail::has_set_from_BigReal) + return R.set_from_BigReal(a, b); + else + return false; } template @@ -80,48 +96,6 @@ bool get_from_complex_double(const RT& R, return false; } -inline bool get_from_BigReal(const ARingQQ& R, - ARingQQ::ElementType& a, - gmp_RR b) -{ - return R.set_from_BigReal(a, b); -} - -inline bool get_from_BigReal(const ARingRR& R, - ARingRR::ElementType& a, - gmp_RR b) -{ - return R.set_from_BigReal(a, b); -} - -inline bool get_from_BigReal(const ARingRRR& R, - ARingRRR::ElementType& a, - gmp_RR b) -{ - return R.set_from_BigReal(a, b); -} - -inline bool get_from_BigReal(const ARingRRi& R, - ARingRRi::ElementType& a, - gmp_RR b) -{ - return R.set_from_BigReal(a, b); -} - -inline bool get_from_BigReal(const ARingCC& R, - ARingCC::ElementType& a, - gmp_RR b) -{ - return R.set_from_BigReal(a, b); -} - -inline bool get_from_BigReal(const ARingCCC& R, - ARingCCC::ElementType& a, - gmp_RR b) -{ - return R.set_from_BigReal(a, b); -} - inline bool get_from_BigComplex(const ARingCCC& R, ARingCCC::ElementType& a, gmp_CC b) @@ -186,13 +160,6 @@ inline bool get_from_BigComplex(const ARingCCi& R, return R.set_from_BigComplex(a, b); } -inline bool get_from_BigReal(const ARingCCi& R, - ARingCCi::ElementType& a, - gmp_RR b) -{ - return R.set_from_BigReal(a, b); -} - inline bool get_from_double(const ARingRR& R, ARingRR::ElementType& a, double b) { return R.set_from_double(a, b); diff --git a/M2/Macaulay2/e/basic-rings/aring.hpp b/M2/Macaulay2/e/basic-rings/aring.hpp index 266901fc5df..0f7483bbbef 100644 --- a/M2/Macaulay2/e/basic-rings/aring.hpp +++ b/M2/Macaulay2/e/basic-rings/aring.hpp @@ -249,12 +249,6 @@ class DummyRing : public SimpleARing (void) a; return false; } - bool set_from_BigReal(elem &result, gmp_RR a) const - { - (void) result; - (void) a; - return false; - } void set_var(elem &result, int v) const { (void) v; From 17236b4fb0d2294c7fa9721866fd442fdb8bd81a Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Fri, 12 Jun 2026 15:40:49 -0400 Subject: [PATCH 02/10] Use templates for get_from_double Replace the hand-written per-ring get_from_double overloads with a single template that uses SFINAE to detect whether a ring defines set_from_double, falling back to false otherwise. As a side effect, ARingQQGMP's existing set_from_double (previously only used by mylift) is now also used for from_double, giving an exact double -> QQ conversion. Co-Authored-By: Claude Sonnet 4.6 --- .../e/basic-rings/aring-translate.hpp | 65 ++++++------------- 1 file changed, 19 insertions(+), 46 deletions(-) diff --git a/M2/Macaulay2/e/basic-rings/aring-translate.hpp b/M2/Macaulay2/e/basic-rings/aring-translate.hpp index a247b30b24d..8048def0563 100644 --- a/M2/Macaulay2/e/basic-rings/aring-translate.hpp +++ b/M2/Macaulay2/e/basic-rings/aring-translate.hpp @@ -32,6 +32,16 @@ namespace M2 { namespace detail { +template +inline constexpr bool has_set_from_double = false; + +template +inline constexpr bool has_set_from_double< + RT, + std::void_t().set_from_double( + std::declval(), std::declval()))>> = + true; + template inline constexpr bool has_set_from_BigReal = false; @@ -43,6 +53,15 @@ inline constexpr bool has_set_from_BigReal< true; } // namespace detail +template +bool get_from_double(const RT& R, typename RT::ElementType& a, double b) +{ + if constexpr (detail::has_set_from_double) + return R.set_from_double(a, b); + else + return false; +} + template bool get_from_BigReal(const RT& R, typename RT::ElementType& a, gmp_RR b) { @@ -76,14 +95,6 @@ bool get_from_BigComplex(const RT& R, typename RT::ElementType& a, gmp_CC b) return false; } template -bool get_from_double(const RT& R, typename RT::ElementType& a, double b) -{ - (void) R; - (void) a; - (void) b; - return false; -} -template bool get_from_complex_double(const RT& R, typename RT::ElementType& a, double re, @@ -110,20 +121,6 @@ inline bool get_from_BigComplex(const ARingCC& R, return R.set_from_BigComplex(a, b); } -inline bool get_from_double(const ARingRRR& R, - ARingRRR::ElementType& a, - double b) -{ - return R.set_from_double(a, b); -} - -inline bool get_from_double(const ARingRRi& R, - ARingRRi::ElementType& a, - double b) -{ - return R.set_from_double(a, b); -} - inline bool get_from_Interval(const ARingRRi& R, ARingRRi::ElementType& a, gmp_RRi b) @@ -139,13 +136,6 @@ inline bool get_from_ComplexInterval(const ARingCCi& R, return true; } -inline bool get_from_double(const ARingCCi& R, - ARingCCi::ElementType& a, - double b) -{ - return R.set_from_double(a, b); -} - inline bool get_from_Interval(const ARingCCi& R, ARingCCi::ElementType& a, gmp_RRi b) @@ -160,23 +150,6 @@ inline bool get_from_BigComplex(const ARingCCi& R, return R.set_from_BigComplex(a, b); } -inline bool get_from_double(const ARingRR& R, ARingRR::ElementType& a, double b) -{ - return R.set_from_double(a, b); -} - -inline bool get_from_double(const ARingCCC& R, - ARingCCC::ElementType& a, - double b) -{ - return R.set_from_double(a, b); -} - -inline bool get_from_double(const ARingCC& R, ARingCC::ElementType& a, double b) -{ - return R.set_from_double(a, b); -} - inline bool get_from_complex_double(const ARingCCC& R, ARingCCC::ElementType& a, double re, From 4167958090e02eb1c04a2a26ab9581babd7f9231 Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Fri, 12 Jun 2026 15:49:14 -0400 Subject: [PATCH 03/10] Use templates for get_from_BigComplex Replace the hand-written per-ring get_from_BigComplex overloads with a single template that uses SFINAE to detect whether a ring defines set_from_BigComplex, falling back to false otherwise. Co-Authored-By: Claude Sonnet 4.6 --- .../e/basic-rings/aring-translate.hpp | 39 +++++++------------ 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/M2/Macaulay2/e/basic-rings/aring-translate.hpp b/M2/Macaulay2/e/basic-rings/aring-translate.hpp index 8048def0563..a08603cafb7 100644 --- a/M2/Macaulay2/e/basic-rings/aring-translate.hpp +++ b/M2/Macaulay2/e/basic-rings/aring-translate.hpp @@ -51,6 +51,16 @@ inline constexpr bool has_set_from_BigReal< std::void_t().set_from_BigReal( std::declval(), std::declval()))>> = true; + +template +inline constexpr bool has_set_from_BigComplex = false; + +template +inline constexpr bool has_set_from_BigComplex< + RT, + std::void_t().set_from_BigComplex( + std::declval(), std::declval()))>> = + true; } // namespace detail template @@ -89,10 +99,10 @@ bool get_from_ComplexInterval(const RT& R, typename RT::ElementType & a, gmp_CCi template bool get_from_BigComplex(const RT& R, typename RT::ElementType& a, gmp_CC b) { - (void) R; - (void) a; - (void) b; - return false; + if constexpr (detail::has_set_from_BigComplex) + return R.set_from_BigComplex(a, b); + else + return false; } template bool get_from_complex_double(const RT& R, @@ -107,20 +117,6 @@ bool get_from_complex_double(const RT& R, return false; } -inline bool get_from_BigComplex(const ARingCCC& R, - ARingCCC::ElementType& a, - gmp_CC b) -{ - return R.set_from_BigComplex(a, b); -} - -inline bool get_from_BigComplex(const ARingCC& R, - ARingCC::ElementType& a, - gmp_CC b) -{ - return R.set_from_BigComplex(a, b); -} - inline bool get_from_Interval(const ARingRRi& R, ARingRRi::ElementType& a, gmp_RRi b) @@ -143,13 +139,6 @@ inline bool get_from_Interval(const ARingCCi& R, return R.set_from_Interval(a, b); } -inline bool get_from_BigComplex(const ARingCCi& R, - ARingCCi::ElementType& a, - gmp_CC b) -{ - return R.set_from_BigComplex(a, b); -} - inline bool get_from_complex_double(const ARingCCC& R, ARingCCC::ElementType& a, double re, From 6308802a3f8efc974abd0947b1be8c239ac8174a Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Fri, 12 Jun 2026 15:50:36 -0400 Subject: [PATCH 04/10] Use templates for get_from_complex_double Replace the hand-written per-ring get_from_complex_double overloads with a single template that uses SFINAE to detect whether a ring defines set_from_complex_double, falling back to false otherwise. Co-Authored-By: Claude Sonnet 4.6 --- .../e/basic-rings/aring-translate.hpp | 59 ++++++++----------- 1 file changed, 23 insertions(+), 36 deletions(-) diff --git a/M2/Macaulay2/e/basic-rings/aring-translate.hpp b/M2/Macaulay2/e/basic-rings/aring-translate.hpp index a08603cafb7..49e224ec85d 100644 --- a/M2/Macaulay2/e/basic-rings/aring-translate.hpp +++ b/M2/Macaulay2/e/basic-rings/aring-translate.hpp @@ -52,6 +52,17 @@ inline constexpr bool has_set_from_BigReal< std::declval(), std::declval()))>> = true; +template +inline constexpr bool has_set_from_complex_double = false; + +template +inline constexpr bool has_set_from_complex_double< + RT, + std::void_t().set_from_complex_double( + std::declval(), + std::declval(), + std::declval()))>> = true; + template inline constexpr bool has_set_from_BigComplex = false; @@ -97,24 +108,24 @@ bool get_from_ComplexInterval(const RT& R, typename RT::ElementType & a, gmp_CCi } template -bool get_from_BigComplex(const RT& R, typename RT::ElementType& a, gmp_CC b) +bool get_from_complex_double(const RT& R, + typename RT::ElementType& a, + double re, + double im) { - if constexpr (detail::has_set_from_BigComplex) - return R.set_from_BigComplex(a, b); + if constexpr (detail::has_set_from_complex_double) + return R.set_from_complex_double(a, re, im); else return false; } + template -bool get_from_complex_double(const RT& R, - typename RT::ElementType& a, - double re, - double im) +bool get_from_BigComplex(const RT& R, typename RT::ElementType& a, gmp_CC b) { - (void) R; - (void) a; - (void) re; - (void) im; - return false; + if constexpr (detail::has_set_from_BigComplex) + return R.set_from_BigComplex(a, b); + else + return false; } inline bool get_from_Interval(const ARingRRi& R, @@ -139,30 +150,6 @@ inline bool get_from_Interval(const ARingCCi& R, return R.set_from_Interval(a, b); } -inline bool get_from_complex_double(const ARingCCC& R, - ARingCCC::ElementType& a, - double re, - double im) -{ - return R.set_from_complex_double(a, re, im); -} - -inline bool get_from_complex_double(const ARingCC& R, - ARingCC::ElementType& a, - double re, - double im) -{ - return R.set_from_complex_double(a, re, im); -} - -inline bool get_from_complex_double(const ARingCCi& R, - ARingCCi::ElementType& a, - double re, - double im) -{ - return R.set_from_complex_double(a, re, im); -} - // Promote an element of one ring to another. // Given a "natural and canonical" map R --> S (depends on the context) // and an element fR of R, set result_fS to be the image of fR under this map. From e20c140427920e9d9571682fc675e13b3a949475 Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Fri, 12 Jun 2026 15:52:12 -0400 Subject: [PATCH 05/10] Use templates for get_from_Interval Replace the hand-written per-ring get_from_Interval overloads with a single template that uses SFINAE to detect whether a ring defines set_from_Interval, falling back to false otherwise. Co-Authored-By: Claude Sonnet 4.6 --- .../e/basic-rings/aring-translate.hpp | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/M2/Macaulay2/e/basic-rings/aring-translate.hpp b/M2/Macaulay2/e/basic-rings/aring-translate.hpp index 49e224ec85d..473ef3f72b4 100644 --- a/M2/Macaulay2/e/basic-rings/aring-translate.hpp +++ b/M2/Macaulay2/e/basic-rings/aring-translate.hpp @@ -52,6 +52,16 @@ inline constexpr bool has_set_from_BigReal< std::declval(), std::declval()))>> = true; +template +inline constexpr bool has_set_from_Interval = false; + +template +inline constexpr bool has_set_from_Interval< + RT, + std::void_t().set_from_Interval( + std::declval(), std::declval()))>> = + true; + template inline constexpr bool has_set_from_complex_double = false; @@ -95,10 +105,10 @@ bool get_from_BigReal(const RT& R, typename RT::ElementType& a, gmp_RR b) template bool get_from_Interval(const RT& R, typename RT::ElementType& a, gmp_RRi b) { - (void) R; - (void) a; - (void) b; - return false; + if constexpr (detail::has_set_from_Interval) + return R.set_from_Interval(a, b); + else + return false; } template @@ -128,13 +138,6 @@ bool get_from_BigComplex(const RT& R, typename RT::ElementType& a, gmp_CC b) return false; } -inline bool get_from_Interval(const ARingRRi& R, - ARingRRi::ElementType& a, - gmp_RRi b) -{ - return R.set_from_Interval(a, b); -} - inline bool get_from_ComplexInterval(const ARingCCi& R, ARingCCi::ElementType& a, gmp_CCi b) @@ -143,13 +146,6 @@ inline bool get_from_ComplexInterval(const ARingCCi& R, return true; } -inline bool get_from_Interval(const ARingCCi& R, - ARingCCi::ElementType& a, - gmp_RRi b) -{ - return R.set_from_Interval(a, b); -} - // Promote an element of one ring to another. // Given a "natural and canonical" map R --> S (depends on the context) // and an element fR of R, set result_fS to be the image of fR under this map. From 74ba32c7cfcc5ce9b8d48ef87160999ab6b2e8fe Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Fri, 12 Jun 2026 15:52:58 -0400 Subject: [PATCH 06/10] Use templates for get_from_ComplexInterval Replace the hand-written ARingCCi overload of get_from_ComplexInterval with a single template that uses SFINAE to detect whether a ring defines set_from_ComplexInterval, falling back to false otherwise. Co-Authored-By: Claude Sonnet 4.6 --- .../e/basic-rings/aring-translate.hpp | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/M2/Macaulay2/e/basic-rings/aring-translate.hpp b/M2/Macaulay2/e/basic-rings/aring-translate.hpp index 473ef3f72b4..fb7e1f0d0a2 100644 --- a/M2/Macaulay2/e/basic-rings/aring-translate.hpp +++ b/M2/Macaulay2/e/basic-rings/aring-translate.hpp @@ -82,6 +82,16 @@ inline constexpr bool has_set_from_BigComplex< std::void_t().set_from_BigComplex( std::declval(), std::declval()))>> = true; + +template +inline constexpr bool has_set_from_ComplexInterval = false; + +template +inline constexpr bool has_set_from_ComplexInterval< + RT, + std::void_t().set_from_ComplexInterval( + std::declval(), std::declval()))>> = + true; } // namespace detail template @@ -111,12 +121,6 @@ bool get_from_Interval(const RT& R, typename RT::ElementType& a, gmp_RRi b) return false; } -template -bool get_from_ComplexInterval(const RT& R, typename RT::ElementType & a, gmp_CCi b) -{ - return false; -} - template bool get_from_complex_double(const RT& R, typename RT::ElementType& a, @@ -138,12 +142,13 @@ bool get_from_BigComplex(const RT& R, typename RT::ElementType& a, gmp_CC b) return false; } -inline bool get_from_ComplexInterval(const ARingCCi& R, - ARingCCi::ElementType& a, - gmp_CCi b) +template +bool get_from_ComplexInterval(const RT& R, typename RT::ElementType & a, gmp_CCi b) { - R.set(a, b); - return true; + if constexpr (detail::has_set_from_ComplexInterval) + return R.set_from_ComplexInterval(a, b); + else + return false; } // Promote an element of one ring to another. From 6eea01736cf0a1a4c3447e26bb5e8bf627667468 Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Fri, 12 Jun 2026 16:17:22 -0400 Subject: [PATCH 07/10] Use a single template for mylift(_, ARingRRi) The three overloads of mylift with second argument ARingRRi (for ARingRR, ARingRRR, and ARingQQ) had identical bodies, differing only in the type of the first ring. Replace them with one function template parameterized on the first ring type. --- .../e/basic-rings/aring-translate.hpp | 37 +++---------------- 1 file changed, 5 insertions(+), 32 deletions(-) diff --git a/M2/Macaulay2/e/basic-rings/aring-translate.hpp b/M2/Macaulay2/e/basic-rings/aring-translate.hpp index fb7e1f0d0a2..20002b1b525 100644 --- a/M2/Macaulay2/e/basic-rings/aring-translate.hpp +++ b/M2/Macaulay2/e/basic-rings/aring-translate.hpp @@ -532,24 +532,11 @@ inline bool mylift(const ARingCC& R, ///////////////////////////////////////////////////// -inline bool mylift(const ARingRR& R, - const ARingRRi& S, - ARingRR::ElementType& result_gR, - const ARingRRi::ElementType& gS) -{ - ARingRRR T(S.get_precision()); - ARingRRR::Element gT(T); - auto gS1 = const_cast(gS); - S.midpoint(gT,gS1); - bool liftstep = mylift(R,T,result_gR,gT); - S.diameter(gT,gS1); - return liftstep && T.is_zero(gT); -} - -inline bool mylift(const ARingRRR& R, - const ARingRRi& S, - ARingRRR::ElementType& result_gR, - const ARingRRi::ElementType& gS) +template +bool mylift(const RingR& R, + const ARingRRi& S, + typename RingR::ElementType& result_gR, + const ARingRRi::ElementType& gS) { ARingRRR T(S.get_precision()); ARingRRR::Element gT(T); @@ -578,20 +565,6 @@ inline bool mylift(const ARingQQ& R, return R.set_from_BigReal(fR, &fS); } -inline bool mylift(const ARingQQ& R, - const ARingRRi& S, - ARingQQ::ElementType& result_gR, - const ARingRRi::ElementType& gS) -{ - ARingRRR T(S.get_precision()); - ARingRRR::Element gT(T); - auto gS1 = const_cast(gS); - S.midpoint(gT,gS1); - bool liftstep = mylift(R,T,result_gR,gT); - S.diameter(gT,gS1); - return liftstep && T.is_zero(gT); -} - // ZZ/p --> ZZ/p. 9 versions NONE OF THESE. // instead: // (1) lift to ZZ (int version?) From 80f438ae3c8c66d581b625c393a9b8d480ebc6a5 Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Fri, 12 Jun 2026 22:12:09 -0400 Subject: [PATCH 08/10] Update tests that work since we can map RR -> QQ now --- M2/Macaulay2/tests/normal/subst7.m2 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/M2/Macaulay2/tests/normal/subst7.m2 b/M2/Macaulay2/tests/normal/subst7.m2 index 67ca89f47e3..594a7c177ab 100644 --- a/M2/Macaulay2/tests/normal/subst7.m2 +++ b/M2/Macaulay2/tests/normal/subst7.m2 @@ -5,12 +5,12 @@ assert try (substitute(v_1,RR);false) else true -- used to crash (<= 1.9.2) assert try (substitute(v_{1},RR);false) else true -- used to crash (<= 1.9.2) assert(ring lift(v_{1},RR_53) === RR_53) --- issue 473: -assert try (sub(matrix{{1.0}},QQ);false) else true -- used to crash (<= 1.9.2) +-- issue 473: +assert( sub(matrix{{1.0}}, QQ) == matrix(QQ, 1) ) -- used to crash (<= 1.9.2) f = map(QQ,RR_53) -assert try (f (matrix{{1.0}}); false) else true -- used to crash (<= 1.9.2) +assert (f (matrix{{1.0}}) == matrix(QQ, 1) ) -- used to crash (<= 1.9.2) C = matrix {{1_CC}} assert(ring lift(C,RR) === RR_53) -- works From 9f2c92a2f679b87d33b9a1c496b9d002564dc6f8 Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Mon, 15 Jun 2026 20:15:34 -0400 Subject: [PATCH 09/10] Use a template for mypromote(ARingQQ, _) Co-Authored-By: Claude Sonnet 4.6 --- .../e/basic-rings/aring-translate.hpp | 57 +++++++------------ 1 file changed, 20 insertions(+), 37 deletions(-) diff --git a/M2/Macaulay2/e/basic-rings/aring-translate.hpp b/M2/Macaulay2/e/basic-rings/aring-translate.hpp index 20002b1b525..8e1dbb9f1d3 100644 --- a/M2/Macaulay2/e/basic-rings/aring-translate.hpp +++ b/M2/Macaulay2/e/basic-rings/aring-translate.hpp @@ -32,6 +32,17 @@ namespace M2 { namespace detail { + +template +inline constexpr bool has_set_from_mpq = false; + +template +inline constexpr bool has_set_from_mpq< + RT, + std::void_t().set_from_mpq( + std::declval(), + std::declval()))>> = true; + template inline constexpr bool has_set_from_double = false; @@ -181,45 +192,17 @@ bool mylift(const RingR& R, } ///////////////////////////////////////////////////// -inline bool mypromote(const ARingQQ& R, - const ARingRR& S, - const ARingQQ::ElementType& fR, - ARingRR::ElementType& fS) -{ - (void) R; - return S.set_from_mpq(fS, &fR); -} -inline bool mypromote(const ARingQQ& R, - const ARingRRR& S, - const ARingQQ::ElementType& fR, - ARingRRR::ElementType& fS) -{ - (void) R; - return S.set_from_mpq(fS, &fR); -} -inline bool mypromote(const ARingQQ& R, - const ARingRRi& S, - const ARingQQ::ElementType& fR, - ARingRRi::ElementType& fS) -{ - (void) R; - return S.set_from_mpq(fS, &fR); -} -inline bool mypromote(const ARingQQ& R, - const ARingCC& S, - const ARingQQ::ElementType& fR, - ARingCC::ElementType& fS) -{ - (void) R; - return S.set_from_mpq(fS, &fR); -} -inline bool mypromote(const ARingQQ& R, - const ARingCCC& S, - const ARingQQ::ElementType& fR, - ARingCCC::ElementType& fS) +template +bool mypromote(const ARingQQ& R, + const RingS& S, + const ARingQQ::ElementType& fR, + typename RingS::ElementType& fS) { (void) R; - return S.set_from_mpq(fS, &fR); + if constexpr (detail::has_set_from_mpq) + return S.set_from_mpq(fS, &fR); + else + return false; } ///////////////////////////////////////////////////// inline bool mypromote(const ARingRR& R, From 4c55d2835c1f75ce5c547c829eb4f4b07f5337eb Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Mon, 15 Jun 2026 20:19:21 -0400 Subject: [PATCH 10/10] Use a template for same-type mypromote Co-Authored-By: Claude Sonnet 4.6 --- .../e/basic-rings/aring-translate.hpp | 56 +++---------------- 1 file changed, 7 insertions(+), 49 deletions(-) diff --git a/M2/Macaulay2/e/basic-rings/aring-translate.hpp b/M2/Macaulay2/e/basic-rings/aring-translate.hpp index 8e1dbb9f1d3..718787389d1 100644 --- a/M2/Macaulay2/e/basic-rings/aring-translate.hpp +++ b/M2/Macaulay2/e/basic-rings/aring-translate.hpp @@ -205,15 +205,17 @@ bool mypromote(const ARingQQ& R, return false; } ///////////////////////////////////////////////////// -inline bool mypromote(const ARingRR& R, - const ARingRR& S, - const ARingRR::ElementType& fR, - ARingRR::ElementType& fS) +template +bool mypromote(const Ring& R, + const Ring& S, + const typename Ring::ElementType& fR, + typename Ring::ElementType& fS) { (void) R; - S.set_from_double(fS, fR); + S.set(fS, fR); return true; } +///////////////////////////////////////////////////// inline bool mypromote(const ARingRR& R, const ARingRRR& S, const ARingRR::ElementType& fR, @@ -242,15 +244,6 @@ inline bool mypromote(const ARingRR& R, return true; } ///////////////////////////////////////////////////// -inline bool mypromote(const ARingRRR& R, - const ARingRRR& S, - const ARingRRR::ElementType& fR, - ARingRRR::ElementType& fS) -{ - (void) R; - S.set(fS, fR); - return true; -} inline bool mypromote(const ARingRRR& R, const ARingRR& S, const ARingRRR::ElementType& fR, @@ -282,15 +275,6 @@ inline bool mypromote(const ARingRRR& R, return true; } ///////////////////////////////////////////////////// -inline bool mypromote(const ARingRRi& R, - const ARingRRi& S, - const ARingRRi::ElementType& fR, - ARingRRi::ElementType& fS) -{ - (void) R; - S.set(fS, fR); - return true; -} inline bool mypromote(const ARingRR& R, const ARingRRi& S, const ARingRR::ElementType& fR, @@ -310,15 +294,6 @@ inline bool mypromote(const ARingRRR& R, return true; } ///////////////////////////////////////////////////// -inline bool mypromote(const ARingCC& R, - const ARingCC& S, - const ARingCC::ElementType& fR, - ARingCC::ElementType& fS) -{ - (void) R; - S.set(fS, fR); - return true; -} inline bool mypromote(const ARingCC& R, const ARingCCC& S, const ARingCC::ElementType& fR, @@ -339,24 +314,7 @@ inline bool mypromote(const ARingCCC& R, S.set_from_BigReals(fS, &fR1.re, &fR1.im); return true; } -inline bool mypromote(const ARingCCC& R, - const ARingCCC& S, - const ARingCCC::ElementType& fR, - ARingCCC::ElementType& fS) -{ - (void) R; - S.set(fS, fR); - return true; -} ///////////////////////////////////////////////////// -inline bool mypromote(const ARingCCi& R, - const ARingCCi& S, - const ARingCCi::ElementType& fR, - ARingCCi::ElementType& fS) -{ - S.set(fS, fR); - return true; -} inline bool mypromote(const ARingRR& R, const ARingCCi& S, const ARingRR::ElementType& fR,