diff --git a/include/xo/numeric/FloatIntegerOps.hpp b/include/xo/numeric/FloatIntegerOps.hpp index 9d21540f..5cf301ad 100644 --- a/include/xo/numeric/FloatIntegerOps.hpp +++ b/include/xo/numeric/FloatIntegerOps.hpp @@ -27,6 +27,9 @@ namespace xo { DFloat * x, DInteger * y); static obj subtract(obj rcx, DFloat * x, DInteger * y); + + static obj cmp_equal(obj rcx, + DFloat * x, DInteger * y); }; class IntegerFloatOps { @@ -42,6 +45,9 @@ namespace xo { DInteger * x, DFloat * y); static obj subtract(obj rcx, DInteger * x, DFloat * y); + + static obj cmp_equal(obj rcx, + DInteger * x, DFloat * y); }; } diff --git a/include/xo/numeric/FloatOps.hpp b/include/xo/numeric/FloatOps.hpp index 75ffb5e4..5f7d06be 100644 --- a/include/xo/numeric/FloatOps.hpp +++ b/include/xo/numeric/FloatOps.hpp @@ -26,6 +26,9 @@ namespace xo { DFloat * x, DFloat * y); static obj subtract(obj rcx, DFloat * x, DFloat * y); + + static obj cmp_equal(obj rcx, + DFloat * x, DFloat * y); }; } diff --git a/include/xo/numeric/IntegerOps.hpp b/include/xo/numeric/IntegerOps.hpp index d839ad36..001a915f 100644 --- a/include/xo/numeric/IntegerOps.hpp +++ b/include/xo/numeric/IntegerOps.hpp @@ -29,6 +29,9 @@ namespace xo { static obj subtract(obj rcx, DInteger * x, DInteger * y); + static obj cmp_equal(obj rcx, + DInteger * x, DInteger * y); + }; } diff --git a/include/xo/numeric/NumericDispatch.hpp b/include/xo/numeric/NumericDispatch.hpp index 0f7a4ffd..58d06565 100644 --- a/include/xo/numeric/NumericDispatch.hpp +++ b/include/xo/numeric/NumericDispatch.hpp @@ -82,6 +82,11 @@ namespace xo { obj x, obj y); + /** compare two numeric values for equality **/ + static obj cmp_equal(obj rcx, + obj x, + obj y); + /** report memory use for owned arenas to @p visitor **/ void visit_pools(const MemorySizeVisitor & visitor); @@ -94,7 +99,8 @@ namespace xo { void register_impl(typename NumericOps::BinaryOp_Impl mul_fn, typename NumericOps::BinaryOp_Impl div_fn, typename NumericOps::BinaryOp_Impl add_fn, - typename NumericOps::BinaryOp_Impl sub_fn) { + typename NumericOps::BinaryOp_Impl sub_fn, + typename NumericOps::BinaryOp_Impl cmpeq_fn) { KeyType key(typeseq::id().seqno(), typeseq::id().seqno()); @@ -104,7 +110,8 @@ namespace xo { = NumericOps::make(mul_fn, div_fn, add_fn, - sub_fn); + sub_fn, + cmpeq_fn); } private: diff --git a/include/xo/numeric/NumericOps.hpp b/include/xo/numeric/NumericOps.hpp index bc8630a6..f85b20f4 100644 --- a/include/xo/numeric/NumericOps.hpp +++ b/include/xo/numeric/NumericOps.hpp @@ -25,13 +25,18 @@ namespace xo { explicit AnonymizedNumericOps(BinaryOp multiply, BinaryOp divide, BinaryOp add, - BinaryOp subtract) - : multiply_{multiply}, divide_{divide}, add_{add}, subtract_{subtract} {} + BinaryOp subtract, + BinaryOp cmpeq) + : multiply_{multiply}, divide_{divide}, add_{add}, subtract_{subtract}, + cmpeq_{cmpeq} {} BinaryOp multiply_ = nullptr; BinaryOp divide_ = nullptr; BinaryOp add_ = nullptr; BinaryOp subtract_ = nullptr; + + /** compare numerics for equality **/ + BinaryOp cmpeq_ = nullptr; }; template @@ -46,11 +51,13 @@ namespace xo { static AnonymizedNumericOps make(BinaryOp_Impl multiply, BinaryOp_Impl divide, BinaryOp_Impl add, - BinaryOp_Impl subtract) { + BinaryOp_Impl subtract, + BinaryOp_Impl cmpeq) { return AnonymizedNumericOps(reinterpret_cast(multiply), reinterpret_cast(divide), reinterpret_cast(add), - reinterpret_cast(subtract)); + reinterpret_cast(subtract), + reinterpret_cast(cmpeq)); } }; diff --git a/include/xo/numeric/NumericPrimitives.hpp b/include/xo/numeric/NumericPrimitives.hpp index f5ce374e..8f9c40db 100644 --- a/include/xo/numeric/NumericPrimitives.hpp +++ b/include/xo/numeric/NumericPrimitives.hpp @@ -22,6 +22,9 @@ namespace xo { 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; + + /** polymorphic (in both arguments) compare (==) **/ + static DPrimitive_gco_2_gco_gco s_cmpeq_gco_gco_pm; }; } } diff --git a/src/numeric/FloatIntegerOps.cpp b/src/numeric/FloatIntegerOps.cpp index 5b15d5bb..476a6745 100644 --- a/src/numeric/FloatIntegerOps.cpp +++ b/src/numeric/FloatIntegerOps.cpp @@ -5,6 +5,7 @@ #include "FloatIntegerOps.hpp" #include "float/INumeric_DFloat.hpp" +#include namespace xo { using xo::mm::AGCObject; @@ -41,6 +42,14 @@ namespace xo { return DFloat::box(rcx.allocator(), x->value() - y->value()); } + obj + FloatIntegerOps::cmp_equal(obj rcx, + DFloat * x, DInteger * y) + { + return DBoolean::box(rcx.allocator(), + x->value() == DFloat::value_type(y->value())); + } + // ----- Integer op Float ----- obj @@ -71,6 +80,14 @@ namespace xo { return DFloat::box(rcx.allocator(), x->value() - y->value()); } + obj + IntegerFloatOps::cmp_equal(obj rcx, + DInteger * x, DFloat * y) + { + return DFloat::box(rcx.allocator(), + DFloat::value_type(x->value() == y->value())); + } + } } diff --git a/src/numeric/FloatOps.cpp b/src/numeric/FloatOps.cpp index 8821e48e..d0aa57aa 100644 --- a/src/numeric/FloatOps.cpp +++ b/src/numeric/FloatOps.cpp @@ -5,6 +5,7 @@ #include "FloatOps.hpp" #include "float/INumeric_DFloat.hpp" +#include namespace xo { using xo::mm::AGCObject; @@ -39,6 +40,13 @@ namespace xo { return DFloat::box(rcx.allocator(), x->value() - y->value()); } + obj + FloatOps::cmp_equal(obj rcx, + DFloat * x, DFloat * y) + { + return DBoolean::box(rcx.allocator(), x->value() == y->value()); + } + } } diff --git a/src/numeric/IntegerOps.cpp b/src/numeric/IntegerOps.cpp index 0f435b74..062cbeef 100644 --- a/src/numeric/IntegerOps.cpp +++ b/src/numeric/IntegerOps.cpp @@ -5,8 +5,10 @@ #include "IntegerOps.hpp" #include "integer/INumeric_DInteger.hpp" +#include namespace xo { + using xo::scm::DBoolean; using xo::mm::AGCObject; namespace scm { @@ -39,6 +41,13 @@ namespace xo { return DInteger::box(rcx.allocator(), x->value() - y->value()); } + obj + IntegerOps::cmp_equal(obj rcx, + DInteger * x, DInteger * y) + { + return DBoolean::box(rcx.allocator(), x->value() == y->value()); + } + } } diff --git a/src/numeric/NumericDispatch.cpp b/src/numeric/NumericDispatch.cpp index ded8c420..935d92eb 100644 --- a/src/numeric/NumericDispatch.cpp +++ b/src/numeric/NumericDispatch.cpp @@ -81,6 +81,22 @@ namespace xo { return (*target_fn)(rcx, x.data(), y.data()); } + obj + NumericDispatch::cmp_equal(obj rcx, + obj x, + obj y) + { + KeyType key(x._typeseq(), y._typeseq()); + + auto target_fn + = NumericDispatch::instance().dispatch_[key].cmpeq_; + + 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 ebbcb30b..28031fac 100644 --- a/src/numeric/NumericPrimitives.cpp +++ b/src/numeric/NumericPrimitives.cpp @@ -27,6 +27,10 @@ namespace xo { NumericPrimitives::s_sub_gco_gco_pm("_sub", &NumericDispatch::subtract); + DPrimitive_gco_2_gco_gco + NumericPrimitives::s_cmpeq_gco_gco_pm("_cmpeq", + &NumericDispatch::cmp_equal); + } /*namespace scm*/ } /*namespace xo*/ diff --git a/src/numeric/numeric_register_facets.cpp b/src/numeric/numeric_register_facets.cpp index 20e2093d..9cc6e1f9 100644 --- a/src/numeric/numeric_register_facets.cpp +++ b/src/numeric/numeric_register_facets.cpp @@ -38,25 +38,29 @@ namespace xo { (&FloatOps::multiply, &FloatOps::divide, &FloatOps::add, - &FloatOps::subtract); + &FloatOps::subtract, + &FloatOps::cmp_equal); NumericDispatch::instance().register_impl (&FloatIntegerOps::multiply, &FloatIntegerOps::divide, &FloatIntegerOps::add, - &FloatIntegerOps::subtract); + &FloatIntegerOps::subtract, + &FloatIntegerOps::cmp_equal); NumericDispatch::instance().register_impl (&IntegerFloatOps::multiply, &IntegerFloatOps::divide, &IntegerFloatOps::add, - &IntegerFloatOps::subtract); + &IntegerFloatOps::subtract, + &IntegerFloatOps::cmp_equal); NumericDispatch::instance().register_impl (&IntegerOps::multiply, &IntegerOps::divide, &IntegerOps::add, - &IntegerOps::subtract); + &IntegerOps::subtract, + &IntegerOps::cmp_equal); log && log(xtag("ANumeric.tseq", typeseq::id()));