diff --git a/include/fintamath/core/MathObjectTypes.hpp b/include/fintamath/core/MathObjectTypes.hpp index 964cc7dcf..25ca434f0 100644 --- a/include/fintamath/core/MathObjectTypes.hpp +++ b/include/fintamath/core/MathObjectTypes.hpp @@ -112,6 +112,7 @@ class MathObjectType { Derivative, Integral, Frac, + FracMixed, PowFunction, Floor, Ceil, diff --git a/include/fintamath/functions/arithmetic/FracMixed.hpp b/include/fintamath/functions/arithmetic/FracMixed.hpp new file mode 100644 index 000000000..9da664593 --- /dev/null +++ b/include/fintamath/functions/arithmetic/FracMixed.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "fintamath/core/IArithmetic.hpp" +#include "fintamath/functions/IFunction.hpp" + +namespace fintamath { + +class FracMixed : public IFunctionCRTP { +public: + std::string toString() const override { + return "frac"; + } + + static MathObjectType getTypeStatic() { + return MathObjectType::FracMixed; + } + +protected: + std::unique_ptr call(const ArgumentRefVector &argsVect) const override; +}; + +} diff --git a/src/fintamath/config/ExpressionConfig.cpp b/src/fintamath/config/ExpressionConfig.cpp index 88fe9a689..7a90d94cb 100644 --- a/src/fintamath/config/ExpressionConfig.cpp +++ b/src/fintamath/config/ExpressionConfig.cpp @@ -21,6 +21,7 @@ #include "fintamath/functions/arithmetic/Add.hpp" #include "fintamath/functions/arithmetic/Div.hpp" #include "fintamath/functions/arithmetic/Frac.hpp" +#include "fintamath/functions/arithmetic/FracMixed.hpp" #include "fintamath/functions/arithmetic/Mul.hpp" #include "fintamath/functions/arithmetic/Neg.hpp" #include "fintamath/functions/arithmetic/Sub.hpp" @@ -160,6 +161,14 @@ struct ExpressionConfig { return divExpr(std::move(args)); }); + Expression::registerFunctionExpressionMaker([](ArgumentPtrVector &&args) { + ArgumentPtr integ = args[0]; + ArgumentPtr numer = args[1]; + ArgumentPtr denom = args[2]; + + return addExpr(integ, divExpr(numer, denom)); + }); + Expression::registerFunctionExpressionMaker([](ArgumentPtrVector &&args) { return AndExpression(std::move(args)).clone(); }); diff --git a/src/fintamath/config/ParserConfig.cpp b/src/fintamath/config/ParserConfig.cpp index db4dc00ee..b68c97ded 100644 --- a/src/fintamath/config/ParserConfig.cpp +++ b/src/fintamath/config/ParserConfig.cpp @@ -9,6 +9,7 @@ #include "fintamath/functions/arithmetic/Add.hpp" #include "fintamath/functions/arithmetic/Div.hpp" #include "fintamath/functions/arithmetic/Frac.hpp" +#include "fintamath/functions/arithmetic/FracMixed.hpp" #include "fintamath/functions/arithmetic/Mul.hpp" #include "fintamath/functions/arithmetic/Neg.hpp" #include "fintamath/functions/arithmetic/Sign.hpp" @@ -225,6 +226,7 @@ struct ParserConfig { IFunction::registerType(); IFunction::registerType(); IFunction::registerType(); + IFunction::registerType(); IFunction::registerType(); IFunction::registerType(); IFunction::registerType(); diff --git a/src/fintamath/functions/arithmetic/FracMixed.cpp b/src/fintamath/functions/arithmetic/FracMixed.cpp new file mode 100644 index 000000000..1fd2397a9 --- /dev/null +++ b/src/fintamath/functions/arithmetic/FracMixed.cpp @@ -0,0 +1,16 @@ +#include "fintamath/functions/arithmetic/FracMixed.hpp" + +#include "fintamath/functions/arithmetic/Add.hpp" +#include "fintamath/functions/arithmetic/Div.hpp" + +namespace fintamath { + +std::unique_ptr FracMixed::call(const ArgumentRefVector &argsVect) const { + const auto &integ = cast(argsVect[0].get()); + const auto &numer = cast(argsVect[1].get()); + const auto &denom = cast(argsVect[2].get()); + + return Add()(integ, *Div()(numer, denom)); +} + +} diff --git a/tests/src/functions/arithmetic/FracMixedTests.cpp b/tests/src/functions/arithmetic/FracMixedTests.cpp new file mode 100644 index 000000000..82657dc3c --- /dev/null +++ b/tests/src/functions/arithmetic/FracMixedTests.cpp @@ -0,0 +1,63 @@ +#include "gtest/gtest.h" + +#include "fintamath/functions/arithmetic/Add.hpp" + +#include "fintamath/exceptions/InvalidInputException.hpp" +#include "fintamath/functions/arithmetic/FracMixed.hpp" +#include "fintamath/functions/arithmetic/Sub.hpp" +#include "fintamath/functions/arithmetic/UnaryPlus.hpp" +#include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Rational.hpp" + +using namespace fintamath; + +const FracMixed f; + +TEST(FracMixedTests, toStringTest) { + EXPECT_EQ(f.toString(), "frac"); +} + +TEST(FracMixedTests, getFunctionTypeTest) { + EXPECT_EQ(f.getFunctionType(), IFunction::Type::Ternary); +} + +TEST(FracMixedTests, callTest) { + EXPECT_EQ(f(Integer(0), Integer(3), Integer(5))->toString(), "3/5"); + EXPECT_EQ(f(Integer(0), Integer(3), Rational(5, 2))->toString(), "6/5"); + EXPECT_EQ(f(Integer(0), Rational(5, 2), Integer(3))->toString(), "5/6"); + EXPECT_EQ(f(Integer(0), Rational(5, 2), Rational(5, 3))->toString(), "3/2"); + + EXPECT_EQ(f(Integer(0), Integer(3), Variable("a"))->toString(), "3/a"); + + EXPECT_THROW(f(Integer(1)), InvalidInputFunctionException); + EXPECT_THROW(f(Rational(2, 3)), InvalidInputFunctionException); + EXPECT_THROW(f(), InvalidInputFunctionException); + EXPECT_THROW(f(Integer(1), Integer(1), Integer(1), Integer(1)), InvalidInputFunctionException); +} + +TEST(FracMixedTests, doArgsMatchTest) { + Integer a; + + EXPECT_FALSE(f.doArgsMatch({})); + EXPECT_FALSE(f.doArgsMatch({a})); + EXPECT_FALSE(f.doArgsMatch({a, a})); + EXPECT_TRUE(f.doArgsMatch({a, a, a})); + EXPECT_FALSE(f.doArgsMatch({a, a, a, a})); +} + +TEST(FracMixedTests, equalsTest) { + EXPECT_EQ(f, f); + EXPECT_EQ(f, FracMixed()); + EXPECT_EQ(FracMixed(), f); + EXPECT_EQ(f, cast(FracMixed())); + EXPECT_EQ(cast(FracMixed()), f); + EXPECT_NE(f, Sub()); + EXPECT_NE(Sub(), f); + EXPECT_NE(f, UnaryPlus()); + EXPECT_NE(UnaryPlus(), f); +} + +TEST(FracMixedTests, getTypeTest) { + EXPECT_EQ(FracMixed::getTypeStatic(), MathObjectType::FracMixed); + EXPECT_EQ(FracMixed().getType(), MathObjectType::FracMixed); +} diff --git a/tests/src/parser/ParserTests.cpp b/tests/src/parser/ParserTests.cpp index ae4f25b6c..b851fb148 100644 --- a/tests/src/parser/ParserTests.cpp +++ b/tests/src/parser/ParserTests.cpp @@ -8,6 +8,7 @@ #include "fintamath/functions/arithmetic/Add.hpp" #include "fintamath/functions/arithmetic/Div.hpp" #include "fintamath/functions/arithmetic/Frac.hpp" +#include "fintamath/functions/arithmetic/FracMixed.hpp" #include "fintamath/functions/arithmetic/Mul.hpp" #include "fintamath/functions/arithmetic/Neg.hpp" #include "fintamath/functions/arithmetic/Sign.hpp" @@ -243,16 +244,12 @@ TEST(ParserTests, parseFunctionTest) { EXPECT_TRUE(is(IFunction::parse("acsch"))); EXPECT_TRUE(is(IFunction::parse("derivative"))); EXPECT_TRUE(is(IFunction::parse("integral"))); - EXPECT_TRUE(is(IFunction::parse("frac"))); + EXPECT_TRUE(is(IFunction::parse("frac", IFunction::Type::Binary))); + EXPECT_TRUE(is(IFunction::parse("frac", IFunction::Type::Ternary))); EXPECT_TRUE(is(IFunction::parse("pow"))); EXPECT_TRUE(is(IFunction::parse("floor"))); EXPECT_TRUE(is(IFunction::parse("ceil"))); - EXPECT_TRUE(is(IFunction::parse("+", IFunction::Type::Binary))); - EXPECT_TRUE(is(IFunction::parse("+", IFunction::Type::Unary))); - EXPECT_TRUE(is(IFunction::parse("-", IFunction::Type::Binary))); - EXPECT_TRUE(is(IFunction::parse("-", IFunction::Type::Unary))); - EXPECT_EQ(IFunction::parse("asdgewfe"), nullptr); EXPECT_EQ(IFunction::parse("1224"), nullptr); }