From 9dca9a8c46da1aa911d2d823e38a7a54a1e63980 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 18 Feb 2026 22:40:37 -0800 Subject: [PATCH] xo-reader2 stack: use NumericDispatch for *,/,+,- ops --- include/xo/numeric/FloatIntegerOps.hpp | 8 +++++ include/xo/numeric/FloatOps.hpp | 4 +++ include/xo/numeric/IntegerOps.hpp | 6 ++++ include/xo/numeric/NumericDispatch.hpp | 22 ++++++++++-- include/xo/numeric/NumericOps.hpp | 16 ++++++--- include/xo/numeric/NumericPrimitives.hpp | 4 +++ src/numeric/FloatIntegerOps.cpp | 29 ++++++++++++++++ src/numeric/FloatOps.cpp | 15 ++++++++ src/numeric/IntegerOps.cpp | 14 ++++++++ src/numeric/NumericDispatch.cpp | 44 +++++++++++++++++++----- src/numeric/NumericPrimitives.cpp | 8 +++++ src/numeric/numeric_register_facets.cpp | 16 ++++++--- 12 files changed, 168 insertions(+), 18 deletions(-) diff --git a/include/xo/numeric/FloatIntegerOps.hpp b/include/xo/numeric/FloatIntegerOps.hpp index 97a2c3f6..9d21540f 100644 --- a/include/xo/numeric/FloatIntegerOps.hpp +++ b/include/xo/numeric/FloatIntegerOps.hpp @@ -23,6 +23,10 @@ namespace xo { DFloat * x, DInteger * y); static obj divide(obj rcx, DFloat * x, DInteger * y); + static obj add(obj rcx, + DFloat * x, DInteger * y); + static obj subtract(obj rcx, + DFloat * x, DInteger * y); }; class IntegerFloatOps { @@ -34,6 +38,10 @@ namespace xo { DInteger * x, DFloat * y); static obj divide(obj rcx, DInteger * x, DFloat * y); + static obj add(obj rcx, + DInteger * x, DFloat * y); + static obj subtract(obj rcx, + DInteger * x, DFloat * y); }; } diff --git a/include/xo/numeric/FloatOps.hpp b/include/xo/numeric/FloatOps.hpp index c3a2c288..75ffb5e4 100644 --- a/include/xo/numeric/FloatOps.hpp +++ b/include/xo/numeric/FloatOps.hpp @@ -22,6 +22,10 @@ namespace xo { DFloat * x, DFloat * y); static obj divide(obj rcx, DFloat * x, DFloat * y); + static obj add(obj rcx, + DFloat * x, DFloat * y); + static obj subtract(obj rcx, + DFloat * x, DFloat * y); }; } diff --git a/include/xo/numeric/IntegerOps.hpp b/include/xo/numeric/IntegerOps.hpp index 4f9138de..d839ad36 100644 --- a/include/xo/numeric/IntegerOps.hpp +++ b/include/xo/numeric/IntegerOps.hpp @@ -23,6 +23,12 @@ namespace xo { static obj divide(obj rcx, DInteger * x, DInteger * y); + static obj add(obj rcx, + DInteger * x, DInteger * y); + + static obj subtract(obj rcx, + DInteger * x, DInteger * y); + }; } diff --git a/include/xo/numeric/NumericDispatch.hpp b/include/xo/numeric/NumericDispatch.hpp index 5174430e..0f7a4ffd 100644 --- a/include/xo/numeric/NumericDispatch.hpp +++ b/include/xo/numeric/NumericDispatch.hpp @@ -70,6 +70,18 @@ namespace xo { obj x, obj y); + /** add w/ runtime polymorphism (double-dispatch) + **/ + static obj add(obj rcx, + obj x, + obj y); + + /** subtract w/ runtime polymorphism (double-dispatch) + **/ + static obj subtract(obj rcx, + obj x, + obj y); + /** report memory use for owned arenas to @p visitor **/ void visit_pools(const MemorySizeVisitor & visitor); @@ -80,13 +92,19 @@ namespace xo { **/ template void register_impl(typename NumericOps::BinaryOp_Impl mul_fn, - typename NumericOps::BinaryOp_Impl div_fn) { + typename NumericOps::BinaryOp_Impl div_fn, + typename NumericOps::BinaryOp_Impl add_fn, + typename NumericOps::BinaryOp_Impl sub_fn) { KeyType key(typeseq::id().seqno(), typeseq::id().seqno()); // note: copying op table so they're in proximity - this->dispatch_[key] = NumericOps::make(mul_fn, div_fn); + this->dispatch_[key] + = NumericOps::make(mul_fn, + div_fn, + add_fn, + sub_fn); } private: diff --git a/include/xo/numeric/NumericOps.hpp b/include/xo/numeric/NumericOps.hpp index 4e900534..bc8630a6 100644 --- a/include/xo/numeric/NumericOps.hpp +++ b/include/xo/numeric/NumericOps.hpp @@ -23,11 +23,15 @@ namespace xo { AnonymizedNumericOps() = default; /** @p multiply to multiply (x,y); allocate from mm **/ explicit AnonymizedNumericOps(BinaryOp multiply, - BinaryOp divide) - : multiply_{multiply}, divide_{divide} {} + BinaryOp divide, + BinaryOp add, + BinaryOp subtract) + : multiply_{multiply}, divide_{divide}, add_{add}, subtract_{subtract} {} BinaryOp multiply_ = nullptr; BinaryOp divide_ = nullptr; + BinaryOp add_ = nullptr; + BinaryOp subtract_ = nullptr; }; template @@ -40,9 +44,13 @@ namespace xo { public: static AnonymizedNumericOps make(BinaryOp_Impl multiply, - BinaryOp_Impl divide) { + BinaryOp_Impl divide, + BinaryOp_Impl add, + BinaryOp_Impl subtract) { return AnonymizedNumericOps(reinterpret_cast(multiply), - reinterpret_cast(divide)); + reinterpret_cast(divide), + reinterpret_cast(add), + reinterpret_cast(subtract)); } }; diff --git a/include/xo/numeric/NumericPrimitives.hpp b/include/xo/numeric/NumericPrimitives.hpp index 3eab681a..f5ce374e 100644 --- a/include/xo/numeric/NumericPrimitives.hpp +++ b/include/xo/numeric/NumericPrimitives.hpp @@ -18,6 +18,10 @@ namespace xo { static DPrimitive_gco_2_gco_gco s_mul_gco_gco_pm; /** polymorphic (in both arguments) divide **/ static DPrimitive_gco_2_gco_gco s_div_gco_gco_pm; + /** polymorphic (in both arguments) add **/ + static DPrimitive_gco_2_gco_gco s_add_gco_gco_pm; + /** polymorphic (in both arguments) subtract **/ + static DPrimitive_gco_2_gco_gco s_sub_gco_gco_pm; }; } } diff --git a/src/numeric/FloatIntegerOps.cpp b/src/numeric/FloatIntegerOps.cpp index 65a106ab..5b15d5bb 100644 --- a/src/numeric/FloatIntegerOps.cpp +++ b/src/numeric/FloatIntegerOps.cpp @@ -27,6 +27,20 @@ namespace xo { return DFloat::box(rcx.allocator(), x->value() / y->value()); } + obj + FloatIntegerOps::add(obj rcx, + DFloat * x, DInteger * y) + { + return DFloat::box(rcx.allocator(), x->value() + y->value()); + } + + obj + FloatIntegerOps::subtract(obj rcx, + DFloat * x, DInteger * y) + { + return DFloat::box(rcx.allocator(), x->value() - y->value()); + } + // ----- Integer op Float ----- obj @@ -42,6 +56,21 @@ namespace xo { { return DFloat::box(rcx.allocator(), x->value() / y->value()); } + + obj + IntegerFloatOps::add(obj rcx, + DInteger * x, DFloat * y) + { + return DFloat::box(rcx.allocator(), x->value() + y->value()); + } + + obj + IntegerFloatOps::subtract(obj rcx, + DInteger * x, DFloat * y) + { + return DFloat::box(rcx.allocator(), x->value() - y->value()); + } + } } diff --git a/src/numeric/FloatOps.cpp b/src/numeric/FloatOps.cpp index 9db149b9..8821e48e 100644 --- a/src/numeric/FloatOps.cpp +++ b/src/numeric/FloatOps.cpp @@ -25,6 +25,21 @@ namespace xo { return DFloat::box(rcx.allocator(), x->value() / y->value()); } + obj + FloatOps::add(obj rcx, + DFloat * x, DFloat * y) + { + return DFloat::box(rcx.allocator(), x->value() + y->value()); + } + + obj + FloatOps::subtract(obj rcx, + DFloat * x, DFloat * y) + { + return DFloat::box(rcx.allocator(), x->value() - y->value()); + } + + } } diff --git a/src/numeric/IntegerOps.cpp b/src/numeric/IntegerOps.cpp index c8322266..0f435b74 100644 --- a/src/numeric/IntegerOps.cpp +++ b/src/numeric/IntegerOps.cpp @@ -25,6 +25,20 @@ namespace xo { return DInteger::box(rcx.allocator(), x->value() / y->value()); } + obj + IntegerOps::add(obj rcx, + DInteger * x, DInteger * y) + { + return DInteger::box(rcx.allocator(), x->value() + y->value()); + } + + obj + IntegerOps::subtract(obj rcx, + DInteger * x, DInteger * y) + { + return DInteger::box(rcx.allocator(), x->value() - y->value()); + } + } } diff --git a/src/numeric/NumericDispatch.cpp b/src/numeric/NumericDispatch.cpp index bfc65586..ded8c420 100644 --- a/src/numeric/NumericDispatch.cpp +++ b/src/numeric/NumericDispatch.cpp @@ -27,6 +27,9 @@ namespace xo { auto target_fn = NumericDispatch::instance().dispatch_[key].multiply_; + if (!target_fn) + assert(false); + return (*target_fn)(rcx, x.data(), y.data()); } @@ -35,23 +38,48 @@ namespace xo { obj x, obj y) { - scope log(XO_DEBUG(true)); - KeyType key(x._typeseq(), y._typeseq()); - log && log(xtag("x.tseq", x._typeseq().seqno()), - xtag("y.tseq", y._typeseq().seqno())); - auto target_fn = NumericDispatch::instance().dispatch_[key].divide_; - log && log(xtag("target_fn", target_fn)); - - assert(target_fn); + if (!target_fn) + assert(false); return (*target_fn)(rcx, x.data(), y.data()); } + obj + NumericDispatch::add(obj rcx, + obj x, + obj y) + { + KeyType key(x._typeseq(), y._typeseq()); + + auto target_fn + = NumericDispatch::instance().dispatch_[key].add_; + + if (!target_fn) + assert(false); + + return (*target_fn)(rcx, x.data(), y.data()); + } + + obj + NumericDispatch::subtract(obj rcx, + obj x, + obj y) + { + KeyType key(x._typeseq(), y._typeseq()); + + auto target_fn + = NumericDispatch::instance().dispatch_[key].subtract_; + + if (!target_fn) + assert(false); + + return (*target_fn)(rcx, x.data(), y.data()); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/numeric/NumericPrimitives.cpp b/src/numeric/NumericPrimitives.cpp index a17de848..ebbcb30b 100644 --- a/src/numeric/NumericPrimitives.cpp +++ b/src/numeric/NumericPrimitives.cpp @@ -19,6 +19,14 @@ namespace xo { NumericPrimitives::s_div_gco_gco_pm("_div", &NumericDispatch::divide); + DPrimitive_gco_2_gco_gco + NumericPrimitives::s_add_gco_gco_pm("_add", + &NumericDispatch::add); + + DPrimitive_gco_2_gco_gco + NumericPrimitives::s_sub_gco_gco_pm("_sub", + &NumericDispatch::subtract); + } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/numeric/numeric_register_facets.cpp b/src/numeric/numeric_register_facets.cpp index 3e2d94a5..20e2093d 100644 --- a/src/numeric/numeric_register_facets.cpp +++ b/src/numeric/numeric_register_facets.cpp @@ -36,19 +36,27 @@ namespace xo { NumericDispatch::instance().register_impl (&FloatOps::multiply, - &FloatOps::divide); + &FloatOps::divide, + &FloatOps::add, + &FloatOps::subtract); NumericDispatch::instance().register_impl (&FloatIntegerOps::multiply, - &FloatIntegerOps::divide); + &FloatIntegerOps::divide, + &FloatIntegerOps::add, + &FloatIntegerOps::subtract); NumericDispatch::instance().register_impl (&IntegerFloatOps::multiply, - &IntegerFloatOps::divide); + &IntegerFloatOps::divide, + &IntegerFloatOps::add, + &IntegerFloatOps::subtract); NumericDispatch::instance().register_impl (&IntegerOps::multiply, - &IntegerOps::divide); + &IntegerOps::divide, + &IntegerOps::add, + &IntegerOps::subtract); log && log(xtag("ANumeric.tseq", typeseq::id()));