Skip to content

Commit

Permalink
Make MathObjectClass similar to reference_wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
fintarin committed Apr 6, 2024
1 parent db03585 commit b5e45d5
Show file tree
Hide file tree
Showing 122 changed files with 179 additions and 167 deletions.
15 changes: 8 additions & 7 deletions include/fintamath/core/MathObjectBody.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
#include "fintamath/core/MathObjectClass.hpp"
#include "fintamath/core/Parser.hpp"

#define FINTAMATH_CLASS_BODY(Class) \
public: \
static constexpr MathObjectClass getClassStatic() { \
return {#Class}; \
} \
\
private:
#define FINTAMATH_CLASS_BODY(Class) \
public: \
static constexpr MathObjectClass getClassStatic() noexcept { \
return className; \
} \
\
private: \
static constexpr MathObjectClass::Name className = #Class;

#define FINTAMATH_PARENT_CLASS_BODY(Class) \
FINTAMATH_CLASS_BODY(Class) \
Expand Down
34 changes: 16 additions & 18 deletions include/fintamath/core/MathObjectClass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,47 +38,45 @@ class MathObjectClass final {
using ParentToChildrenMap = std::unordered_map<MathObjectClass, Children>;

public:
constexpr MathObjectClass(const Name inName) : name(inName) {
constexpr MathObjectClass(const Name &inName) noexcept : name(&inName) {
}

constexpr Name getName() const {
return name;
constexpr const Name &getName() const noexcept {
return *name;
}

constexpr bool operator==(const MathObjectClass rhs) const {
return name == rhs.name;
}
constexpr bool operator==(const MathObjectClass &rhs) const noexcept = default;

std::strong_ordering operator<=>(MathObjectClass rhs) const;
std::strong_ordering operator<=>(const MathObjectClass &rhs) const noexcept;

std::optional<MathObjectClass> getParent() const;
std::optional<MathObjectClass> getParent() const noexcept;

const Children &getChildren(bool recursive = false) const;
const Children &getChildren(bool recursive = false) const noexcept;

template <typename Parent, std::derived_from<Parent> Child>
static void bindTypes();
static void bindTypes() noexcept;

private:
Id getId() const;
Id getId() const noexcept;

static ClassToIdMap &getClassToIdMap();
static ClassToIdMap &getClassToIdMap() noexcept;

static ChildToParentMap &getChildToParentMap();
static ChildToParentMap &getChildToParentMap() noexcept;

static ParentToChildrenMap &getParentToChildrenMap();
static ParentToChildrenMap &getParentToChildrenMap() noexcept;

static ParentToChildrenMap &getParentToRecursiveChildrenMap();
static ParentToChildrenMap &getParentToRecursiveChildrenMap() noexcept;

private:
Name name;
const Name *name;

inline static Id maxId = 0;

[[maybe_unused]] inline static const detail::Config config;
};

template <typename Parent, std::derived_from<Parent> Child>
void MathObjectClass::bindTypes() {
void MathObjectClass::bindTypes() noexcept {
MathObjectClass parent = Parent::getClassStatic();
MathObjectClass child = Child::getClassStatic();

Expand All @@ -98,5 +96,5 @@ void MathObjectClass::bindTypes() {
}

inline size_t std::hash<fintamath::MathObjectClass>::operator()(const fintamath::MathObjectClass &rhs) const noexcept {
return std::hash<fintamath::MathObjectClass::Name>{}(rhs.getName());
return std::hash<const fintamath::MathObjectClass::Name *>{}(&rhs.getName());
}
2 changes: 1 addition & 1 deletion include/fintamath/core/MathObjectUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace fintamath {

class IMathObject;

inline bool is(const MathObjectClass to, const MathObjectClass from) {
inline bool is(const MathObjectClass &to, const MathObjectClass &from) {
return to == from || to.getChildren(true).contains(from);
}

Expand Down
22 changes: 11 additions & 11 deletions src/fintamath/core/MathObjectClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace fintamath {

std::strong_ordering MathObjectClass::operator<=>(const MathObjectClass rhs) const {
std::strong_ordering MathObjectClass::operator<=>(const MathObjectClass &rhs) const noexcept {
const Id lhsId = getId();
const Id rhsId = rhs.getId();

Expand All @@ -11,40 +11,40 @@ std::strong_ordering MathObjectClass::operator<=>(const MathObjectClass rhs) con
: name <=> rhs.name;
}

std::optional<MathObjectClass> MathObjectClass::getParent() const {
const auto iter = getChildToParentMap().find(name);
std::optional<MathObjectClass> MathObjectClass::getParent() const noexcept {
const auto iter = getChildToParentMap().find(*name);
return iter != getChildToParentMap().end() ? iter->second : std::optional<MathObjectClass>{};
}

const MathObjectClass::Children &MathObjectClass::getChildren(const bool recursive) const {
const MathObjectClass::Children &MathObjectClass::getChildren(const bool recursive) const noexcept {
if (recursive) {
return getParentToRecursiveChildrenMap()[name];
return getParentToRecursiveChildrenMap()[*name];
}

return getParentToChildrenMap()[name];
return getParentToChildrenMap()[*name];
}

MathObjectClass::Id MathObjectClass::getId() const {
MathObjectClass::Id MathObjectClass::getId() const noexcept {
const auto classToId = getClassToIdMap().find(*this);
return classToId != getClassToIdMap().end() ? classToId->second : 0;
}

MathObjectClass::ClassToIdMap &MathObjectClass::getClassToIdMap() {
MathObjectClass::ClassToIdMap &MathObjectClass::getClassToIdMap() noexcept {
static ClassToIdMap map;
return map;
}

MathObjectClass::ChildToParentMap &MathObjectClass::getChildToParentMap() {
MathObjectClass::ChildToParentMap &MathObjectClass::getChildToParentMap() noexcept {
static ChildToParentMap map;
return map;
}

MathObjectClass::ParentToChildrenMap &MathObjectClass::getParentToChildrenMap() {
MathObjectClass::ParentToChildrenMap &MathObjectClass::getParentToChildrenMap() noexcept {
static ParentToChildrenMap map;
return map;
}

MathObjectClass::ParentToChildrenMap &MathObjectClass::getParentToRecursiveChildrenMap() {
MathObjectClass::ParentToChildrenMap &MathObjectClass::getParentToRecursiveChildrenMap() noexcept {
static ParentToChildrenMap map;
return map;
}
Expand Down
2 changes: 1 addition & 1 deletion tests/src/core/IArithmeticTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,6 @@ TEST(IArithmeticTests, negateTest) {
}

TEST(IArithmeticTests, getClassTest) {
EXPECT_EQ(IArithmetic::getClassStatic(), MathObjectClass("IArithmetic"));
EXPECT_EQ(IArithmetic::getClassStatic().getName(), "IArithmetic");
EXPECT_EQ(IArithmetic::getClassStatic().getParent(), IMathObject::getClassStatic());
}
2 changes: 1 addition & 1 deletion tests/src/core/IComparableTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,6 @@ TEST(IComparableTests, moreEqualsTest) {
}

TEST(IComparableTests, getClassTest) {
EXPECT_EQ(IComparable::getClassStatic(), MathObjectClass("IComparable"));
EXPECT_EQ(IComparable::getClassStatic().getName(), "IComparable");
EXPECT_EQ(IComparable::getClassStatic().getParent(), IArithmetic::getClassStatic());
}
4 changes: 2 additions & 2 deletions tests/src/core/IMathObjectTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,9 @@ TEST(IMathObjectTests, outputTest) {
}

TEST(IMathObjectTests, getClassTest) {
EXPECT_EQ(IMathObject::getClassStatic(), MathObjectClass("IMathObject"));
EXPECT_EQ(IMathObject::getClassStatic().getName(), "IMathObject");
EXPECT_FALSE(IMathObject::getClassStatic().getParent());

EXPECT_EQ(TestMathObject().getClass(), MathObjectClass("TestMathObject"));
EXPECT_EQ(TestMathObject().getClass().getName(), "TestMathObject");
EXPECT_EQ(TestMathObject().getClass().getParent(), IMathObject::getClassStatic());
}
31 changes: 22 additions & 9 deletions tests/src/core/MathObjectClassTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,18 @@ class OtherChildTest : public IParentTest2 {
return 0;
}();

static constexpr std::string_view testClassName = "Test";

}

TEST(MathObjectClassTests, constructorTest) {
{
constexpr MathObjectClass t("Test");
EXPECT_EQ(t.getName(), "Test");
constexpr MathObjectClass t(testClassName);
EXPECT_EQ(t.getName(), testClassName);
}
{
MathObjectClass t("Test");
EXPECT_EQ(t.getName(), "Test");
MathObjectClass t(testClassName);
EXPECT_EQ(t.getName(), testClassName);
}
}

Expand All @@ -80,7 +82,7 @@ TEST(MathObjectClassTests, getNameTest) {
}

TEST(MathObjectClassTests, getParentTest) {
EXPECT_FALSE(MathObjectClass("Test").getParent());
EXPECT_FALSE(MathObjectClass(testClassName).getParent());

EXPECT_FALSE(ISuperParentTest::getClassStatic().getParent());

Expand All @@ -93,7 +95,7 @@ TEST(MathObjectClassTests, getParentTest) {
}

TEST(MathObjectClassTests, getChildrenTest) {
EXPECT_EQ(MathObjectClass("Test").getChildren().size(), 0);
EXPECT_EQ(MathObjectClass(testClassName).getChildren().size(), 0);

EXPECT_EQ(ISuperParentTest::getClassStatic().getChildren().size(), 2);

Expand All @@ -106,7 +108,7 @@ TEST(MathObjectClassTests, getChildrenTest) {
}

TEST(MathObjectClassTests, getChildrenRecursiveTest) {
EXPECT_EQ(MathObjectClass("Test").getChildren(true).size(), 0);
EXPECT_EQ(MathObjectClass(testClassName).getChildren(true).size(), 0);

EXPECT_EQ(ISuperParentTest::getClassStatic().getChildren(true).size(), 5);

Expand All @@ -127,6 +129,17 @@ TEST(MathObjectClassTests, bindTypesTest) {
}

TEST(MathObjectClassTests, hashTest) {
EXPECT_EQ(std::hash<MathObjectClass>{}(MathObjectClass("Test")),
std::hash<MathObjectClass::Name>{}("Test"));
EXPECT_EQ(std::hash<MathObjectClass>{}(MathObjectClass(testClassName)),
std::hash<MathObjectClass>{}(MathObjectClass(testClassName)));
EXPECT_NE(std::hash<MathObjectClass>{}(MathObjectClass(testClassName)),
std::hash<MathObjectClass>{}(IParentTest1::getClassStatic()));
EXPECT_NE(std::hash<MathObjectClass>{}(IParentTest2::getClassStatic()),
std::hash<MathObjectClass>{}(MathObjectClass(testClassName)));

EXPECT_EQ(std::hash<MathObjectClass>{}(ChildTest1::getClassStatic()),
std::hash<MathObjectClass>{}(ChildTest1::getClassStatic()));
EXPECT_NE(std::hash<MathObjectClass>{}(ChildTest1::getClassStatic()),
std::hash<MathObjectClass>{}(IParentTest1::getClassStatic()));
EXPECT_NE(std::hash<MathObjectClass>{}(IParentTest2::getClassStatic()),
std::hash<MathObjectClass>{}(ChildTest1::getClassStatic()));
}
2 changes: 1 addition & 1 deletion tests/src/expressions/ExpressionTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,6 @@ TEST(ExpressionTests, equalsTest) {
}

TEST(ExpressionTests, getClassTest) {
EXPECT_EQ(Expression().getClass(), MathObjectClass("Expression"));
EXPECT_EQ(Expression().getClass().getName(), "Expression");
EXPECT_EQ(Expression().getClassStatic().getParent(), IExpression::getClassStatic());
}
2 changes: 1 addition & 1 deletion tests/src/expressions/FunctionExpressionTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,6 @@ TEST(FunctionExpressionTests, stringConstructorTest) {

TEST(FunctionExpressionTests, getClassTest) {
auto expr = makeExpr(TestBinaryOperator(), Integer(0), Integer(0));
EXPECT_EQ(expr->getClass(), MathObjectClass("FunctionExpression"));
EXPECT_EQ(expr->getClass().getName(), "FunctionExpression");
EXPECT_EQ(expr->getClass().getParent(), IExpression::getClassStatic());
}
2 changes: 1 addition & 1 deletion tests/src/expressions/IExpressionTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,6 @@ TEST(IExpressionTests, toMinimalObjectTest) {
}

TEST(IExpressionTests, getClassTest) {
EXPECT_EQ(IExpression::getClassStatic(), MathObjectClass("IExpression"));
EXPECT_EQ(IExpression::getClassStatic().getName(), "IExpression");
EXPECT_EQ(IExpression::getClassStatic().getParent(), IMathObject::getClassStatic());
}
2 changes: 1 addition & 1 deletion tests/src/expressions/binary/CompExprTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ using namespace fintamath;
TEST(CompExprTests, getClassTest) {
const auto expr = eqvExpr(Integer(0), Integer(0));

EXPECT_EQ(expr->getClass(), MathObjectClass("CompExpr"));
EXPECT_EQ(expr->getClass().getName(), "CompExpr");
EXPECT_EQ(expr->getClass().getParent(), IBinaryExpression::getClassStatic());
}
2 changes: 1 addition & 1 deletion tests/src/expressions/binary/DerivativeExprTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ using namespace fintamath;
TEST(DerivativeExprTests, getClassTest) {
const auto expr = derivativeExpr(Integer(0), Variable("x"));

EXPECT_EQ(expr->getClass(), MathObjectClass("DerivativeExpr"));
EXPECT_EQ(expr->getClass().getName(), "DerivativeExpr");
EXPECT_EQ(expr->getClass().getParent(), IBinaryExpression::getClassStatic());
}
2 changes: 1 addition & 1 deletion tests/src/expressions/binary/DivExprTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ using namespace fintamath;
TEST(DivExprTests, getClassTest) {
const auto expr = divExpr(Integer(0), Integer(0));

EXPECT_EQ(expr->getClass(), MathObjectClass("DivExpr"));
EXPECT_EQ(expr->getClass().getName(), "DivExpr");
EXPECT_EQ(expr->getClass().getParent(), IBinaryExpression::getClassStatic());
}
2 changes: 1 addition & 1 deletion tests/src/expressions/binary/IntegralExprTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ using namespace fintamath;
TEST(IntegralExprTests, getClassTest) {
const auto expr = integralExpr(Integer(0), Variable("x"));

EXPECT_EQ(expr->getClass(), MathObjectClass("IntegralExpr"));
EXPECT_EQ(expr->getClass().getName(), "IntegralExpr");
EXPECT_EQ(expr->getClass().getParent(), IBinaryExpression::getClassStatic());
}
2 changes: 1 addition & 1 deletion tests/src/expressions/binary/LogExprTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ using namespace fintamath;
TEST(LogExprTests, getClassTest) {
const auto expr = logExpr(Integer(0), Integer(0));

EXPECT_EQ(expr->getClass(), MathObjectClass("LogExpr"));
EXPECT_EQ(expr->getClass().getName(), "LogExpr");
EXPECT_EQ(expr->getClass().getParent(), IBinaryExpression::getClassStatic());
}
2 changes: 1 addition & 1 deletion tests/src/expressions/binary/PowExprTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ using namespace fintamath;
TEST(PowExprTests, getClassTest) {
const auto expr = powExpr(Integer(0), Integer(0));

EXPECT_EQ(expr->getClass(), MathObjectClass("PowExpr"));
EXPECT_EQ(expr->getClass().getName(), "PowExpr");
EXPECT_EQ(expr->getClass().getParent(), IBinaryExpression::getClassStatic());
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,6 @@ TEST(IBinaryExpressionTests, toMinimalObjectTest) {
}

TEST(IBinaryExpressionTests, getClassTest) {
EXPECT_EQ(IBinaryExpression::getClassStatic(), MathObjectClass("IBinaryExpression"));
EXPECT_EQ(IBinaryExpression::getClassStatic().getName(), "IBinaryExpression");
EXPECT_EQ(IBinaryExpression::getClassStatic().getParent(), IExpression::getClassStatic());
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,6 @@ TEST(IPolynomExpressionTests, toMinimalObjectTest) {
}

TEST(IPolynomExpressionTests, getClassTest) {
EXPECT_EQ(IPolynomExpression::getClassStatic(), MathObjectClass("IPolynomExpression"));
EXPECT_EQ(IPolynomExpression::getClassStatic().getName(), "IPolynomExpression");
EXPECT_EQ(IPolynomExpression::getClassStatic().getParent(), IExpression::getClassStatic());
}
2 changes: 1 addition & 1 deletion tests/src/expressions/interfaces/IUnaryExpressionTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,6 @@ TEST(IUnaryExpressionTests, toMinimalObjectTest) {
}

TEST(IUnaryExpressionTests, getClassTest) {
EXPECT_EQ(IUnaryExpression::getClassStatic(), MathObjectClass("IUnaryExpression"));
EXPECT_EQ(IUnaryExpression::getClassStatic().getName(), "IUnaryExpression");
EXPECT_EQ(IUnaryExpression::getClassStatic().getParent(), IExpression::getClassStatic());
}
2 changes: 1 addition & 1 deletion tests/src/expressions/polynomial/AddExprTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ using namespace fintamath;
TEST(AddExprTests, getClassTest) {
const auto expr = addExpr(Integer(0), Integer(0));

EXPECT_EQ(expr->getClass(), MathObjectClass("AddExpr"));
EXPECT_EQ(expr->getClass().getName(), "AddExpr");
EXPECT_EQ(expr->getClass().getParent(), IPolynomExpression::getClassStatic());
}
2 changes: 1 addition & 1 deletion tests/src/expressions/polynomial/AndExprTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ using namespace fintamath;
TEST(AndExprTests, getClassTest) {
const auto expr = andExpr(Boolean(), Boolean());

EXPECT_EQ(expr->getClass(), MathObjectClass("AndExpr"));
EXPECT_EQ(expr->getClass().getName(), "AndExpr");
EXPECT_EQ(expr->getClass().getParent(), IPolynomExpression::getClassStatic());
}
2 changes: 1 addition & 1 deletion tests/src/expressions/polynomial/MinMaxExprTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ using namespace fintamath;
TEST(MinMaxExprTests, getClassTest) {
const auto expr = minExpr(Integer(0), Integer(0));

EXPECT_EQ(expr->getClass(), MathObjectClass("MinMaxExpr"));
EXPECT_EQ(expr->getClass().getName(), "MinMaxExpr");
EXPECT_EQ(expr->getClass().getParent(), IPolynomExpression::getClassStatic());
}
2 changes: 1 addition & 1 deletion tests/src/expressions/polynomial/MulExprTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ using namespace fintamath;
TEST(MulExprTests, getClassTest) {
const auto expr = mulExpr(Integer(0), Integer(0));

EXPECT_EQ(expr->getClass(), MathObjectClass("MulExpr"));
EXPECT_EQ(expr->getClass().getName(), "MulExpr");
EXPECT_EQ(expr->getClass().getParent(), IPolynomExpression::getClassStatic());
}
2 changes: 1 addition & 1 deletion tests/src/expressions/polynomial/OrExprTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ using namespace fintamath;
TEST(OrExprTests, getClassTest) {
const auto expr = orExpr(Boolean(), Boolean());

EXPECT_EQ(expr->getClass(), MathObjectClass("OrExpr"));
EXPECT_EQ(expr->getClass().getName(), "OrExpr");
EXPECT_EQ(expr->getClass().getParent(), IPolynomExpression::getClassStatic());
}
Loading

0 comments on commit b5e45d5

Please sign in to comment.