Skip to content

Commit

Permalink
Remove multimethods in IArithmetic
Browse files Browse the repository at this point in the history
  • Loading branch information
fintarin committed Jul 27, 2023
1 parent 10e3a89 commit b03be11
Show file tree
Hide file tree
Showing 9 changed files with 41 additions and 113 deletions.
40 changes: 0 additions & 40 deletions include/fintamath/core/IArithmetic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,18 @@ namespace fintamath {
class IArithmetic : public IMathObject {
public:
friend inline std::unique_ptr<IArithmetic> operator+(const IArithmetic &lhs, const IArithmetic &rhs) {
if (auto res = IArithmetic::getMultiAdd()(lhs, rhs)) {
return res;
}
return lhs.addAbstract(rhs);
}

friend inline std::unique_ptr<IArithmetic> operator-(const IArithmetic &lhs, const IArithmetic &rhs) {
if (auto res = IArithmetic::getMultiSub()(lhs, rhs)) {
return res;
}
return lhs.substractAbstract(rhs);
}

friend inline std::unique_ptr<IArithmetic> operator*(const IArithmetic &lhs, const IArithmetic &rhs) {
if (auto res = IArithmetic::getMultiMul()(lhs, rhs)) {
return res;
}
return lhs.multiplyAbstract(rhs);
}

friend inline std::unique_ptr<IArithmetic> operator/(const IArithmetic &lhs, const IArithmetic &rhs) {
if (auto res = IArithmetic::getMultiDiv()(lhs, rhs)) {
return res;
}
return lhs.divideAbstract(rhs);
}

Expand All @@ -49,26 +37,6 @@ class IArithmetic : public IMathObject {
return rhs.negateAbstract();
}

template <typename Lhs, typename Rhs, typename Func>
static void addMultiAddFunction(const Func &func) {
getMultiAdd().add<Lhs, Rhs>(func);
}

template <typename Lhs, typename Rhs, typename Func>
static void addMultiSubFunction(const Func &func) {
getMultiSub().add<Lhs, Rhs>(func);
}

template <typename Lhs, typename Rhs, typename Func>
static void addMultiMulFunction(const Func &func) {
getMultiMul().add<Lhs, Rhs>(func);
}

template <typename Lhs, typename Rhs, typename Func>
static void addMultiDivFunction(const Func &func) {
getMultiDiv().add<Lhs, Rhs>(func);
}

template <typename T, typename = std::enable_if_t<std::is_base_of_v<IArithmetic, T>>>
static void registerType() {
Parser::registerType<T>(getParser());
Expand Down Expand Up @@ -101,14 +69,6 @@ class IArithmetic : public IMathObject {
virtual std::unique_ptr<IArithmetic> unaryPlusAbstract() const = 0;

private:
static MultiMethod<std::unique_ptr<IArithmetic>(const IArithmetic &, const IArithmetic &)> &getMultiAdd();

static MultiMethod<std::unique_ptr<IArithmetic>(const IArithmetic &, const IArithmetic &)> &getMultiSub();

static MultiMethod<std::unique_ptr<IArithmetic>(const IArithmetic &, const IArithmetic &)> &getMultiMul();

static MultiMethod<std::unique_ptr<IArithmetic>(const IArithmetic &, const IArithmetic &)> &getMultiDiv();

static Parser::Vector<std::unique_ptr<IArithmetic>, const std::string &> &getParser();
};

Expand Down
5 changes: 5 additions & 0 deletions include/fintamath/functions/arithmetic/Div.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

namespace fintamath {

class Integer;

class Div : public IOperatorCRTP<IArithmetic, Div, IArithmetic, IArithmetic> {
public:
Div() : IOperatorCRTP(IOperator::Priority::Multiplication, false) {
Expand All @@ -20,6 +22,9 @@ class Div : public IOperatorCRTP<IArithmetic, Div, IArithmetic, IArithmetic> {

protected:
std::unique_ptr<IMathObject> call(const ArgumentsRefVector &argsVect) const override;

private:
static std::unique_ptr<IMathObject> divSimpl(const Integer &lhs, const Integer &rhs);
};

}
45 changes: 0 additions & 45 deletions src/fintamath/config/ArithmeticConfig.cpp

This file was deleted.

2 changes: 1 addition & 1 deletion src/fintamath/config/ExpressionConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ struct ExpressionConfig {

Expression::registerFunctionExpressionMaker<Root>([](const ArgumentsPtrVector &args) {
if (const auto num = cast<INumber>(args.back())) {
return makeExpr(Pow(), args.front(), Integer(1) / (*num));
return makeExpr(Pow(), args.front(), Rational(1) / (*num));
}

return makeExpr(Pow(), args.front(), makeExpr(Div(), std::make_shared<Integer>(1), args.back()));
Expand Down
31 changes: 30 additions & 1 deletion src/fintamath/functions/arithmetic/Div.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,38 @@
#include "fintamath/numbers/INumber.hpp"

#include "fintamath/functions/arithmetic/Div.hpp"
#include "fintamath/numbers/Integer.hpp"
#include "fintamath/numbers/Rational.hpp"

namespace fintamath {

std::unique_ptr<IMathObject> Div::call(const ArgumentsRefVector &argsVect) const {
return cast<IArithmetic>(argsVect.front().get()) / cast<IArithmetic>(argsVect.back().get());
static const auto multiPow = [] {
static MultiMethod<std::unique_ptr<IMathObject>(const IArithmetic &, const IArithmetic &)> outMultiPow;

outMultiPow.add<Integer, Integer>([](const Integer &lhs, const Integer &rhs) {
return divSimpl(lhs, rhs);
});

return outMultiPow;
}();

const auto &lhs = cast<IArithmetic>(argsVect.front().get());
const auto &rhs = cast<IArithmetic>(argsVect.back().get());

if (auto res = multiPow(lhs, rhs)) {
return res;
}

return lhs / rhs;
}

std::unique_ptr<IMathObject> Div::divSimpl(const Integer &lhs, const Integer &rhs) {
if (lhs % rhs != 0) {
return Rational(lhs, rhs).toMinimalObject();
}

return (lhs / rhs).toMinimalObject();
}

}
5 changes: 3 additions & 2 deletions src/fintamath/functions/other/Percent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@

namespace fintamath {

const Integer PERCENT_VALUE = 100;
const Rational PERCENT_VALUE = 100;

std::unique_ptr<IMathObject> Percent::call(const ArgumentsRefVector &argsVect) const {
return (cast<INumber>(argsVect.front().get()) / PERCENT_VALUE)->toMinimalObject();
const auto &rhs = cast<INumber>(argsVect.front().get());
return (rhs / PERCENT_VALUE)->toMinimalObject();
}

}
2 changes: 1 addition & 1 deletion src/fintamath/functions/powers/Root.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ std::unique_ptr<IMathObject> Root::rootSimpl(const Rational &lhs, const Integer
}

std::unique_ptr<IMathObject> Root::rootSimpl(const Real &lhs, const Integer &rhs) {
return Pow()(lhs, 1 / Rational(rhs));
return Pow()(lhs, Rational(1, rhs));
}

}
22 changes: 0 additions & 22 deletions tests/src/core/IArithmeticTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,28 +198,6 @@ TEST(IArithmeticTests, negateTest) {
EXPECT_EQ((-Integer(1)).toString(), "-1");
}

TEST(IArithmeticTests, multimethodsTest) {
IArithmetic::addMultiAddFunction<TestArithmetic, Integer>([](const TestArithmetic &lhs, const Integer &rhs) {
return cast<IArithmetic>(std::make_unique<Integer>(0));
});
EXPECT_EQ(*(TestArithmetic() + Integer(1)), Integer(0));

IArithmetic::addMultiSubFunction<TestArithmetic, Integer>([](const TestArithmetic &lhs, const Integer &rhs) {
return cast<IArithmetic>(std::make_unique<Integer>(0));
});
EXPECT_EQ(*(TestArithmetic() - Integer(1)), Integer(0));

IArithmetic::addMultiMulFunction<TestArithmetic, Integer>([](const TestArithmetic &lhs, const Integer &rhs) {
return cast<IArithmetic>(std::make_unique<Integer>(0));
});
EXPECT_EQ(*(TestArithmetic() * Integer(1)), Integer(0));

IArithmetic::addMultiDivFunction<TestArithmetic, Integer>([](const TestArithmetic &lhs, const Integer &rhs) {
return cast<IArithmetic>(std::make_unique<Integer>(0));
});
EXPECT_EQ(*(TestArithmetic() / Integer(1)), Integer(0));
}

TEST(IArithmeticTests, getTypeIdTest) {
EXPECT_EQ(IArithmetic::getTypeIdStatic(), MathObjectTypeId(MathObjectType::IArithmetic));
}
2 changes: 1 addition & 1 deletion tests/src/numbers/INumberTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ TEST(INumberTests, divTest) {
std::unique_ptr<INumber> m3 = std::make_unique<Rational>(2);
std::unique_ptr<INumber> m4 = std::make_unique<Rational>(1, 2);

EXPECT_EQ((*m1 / *m2)->toString(), "1/5");
EXPECT_EQ((*m1 / *m2)->toString(), "0");

EXPECT_EQ((*m1 / *m1)->toString(), "1");
EXPECT_EQ((*m3 / *m3)->toString(), "1");
Expand Down

0 comments on commit b03be11

Please sign in to comment.