Skip to content

Commit

Permalink
New MathObjectClass
Browse files Browse the repository at this point in the history
  • Loading branch information
fintarin committed Apr 8, 2024
1 parent c773af7 commit 11028e6
Show file tree
Hide file tree
Showing 253 changed files with 693 additions and 769 deletions.
2 changes: 1 addition & 1 deletion include/fintamath/core/IArithmetic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
namespace fintamath {

class IArithmetic : public IMathObject {
FINTAMATH_PARENT_CLASS_BODY(IArithmetic)
FINTAMATH_PARENT_CLASS_BODY(IArithmetic, IMathObject)

public:
friend std::unique_ptr<IArithmetic> operator+(const IArithmetic &lhs, const IArithmetic &rhs) {
Expand Down
2 changes: 1 addition & 1 deletion include/fintamath/core/IComparable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
namespace fintamath {

class IComparable : public IArithmetic {
FINTAMATH_PARENT_CLASS_BODY(IComparable)
FINTAMATH_PARENT_CLASS_BODY(IComparable, IArithmetic)

public:
friend std::strong_ordering operator<=>(const IComparable &lhs, const IComparable &rhs) {
Expand Down
9 changes: 5 additions & 4 deletions include/fintamath/core/IMathObject.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,30 @@
#include "fintamath/core/MathObjectBody.hpp"
#include "fintamath/core/MathObjectClass.hpp"
#include "fintamath/core/MathObjectUtils.hpp"
#include "fintamath/core/None.hpp"
#include "fintamath/core/Parser.hpp"

namespace fintamath {

class IMathObject {
FINTAMATH_PARENT_CLASS_BODY(IMathObject)
FINTAMATH_PARENT_CLASS_BODY(IMathObject, None)

public:
virtual ~IMathObject() = default;
virtual ~IMathObject() noexcept = default;

virtual std::unique_ptr<IMathObject> clone() const & = 0;

virtual std::unique_ptr<IMathObject> clone() && = 0;

virtual std::string toString() const {
return std::string(getClass().getName());
return std::string(getClass()->getName());
}

virtual std::unique_ptr<IMathObject> toMinimalObject() const {
return clone();
}

virtual MathObjectClass getClass() const = 0;
virtual MathObjectClass getClass() const noexcept = 0;

friend bool operator==(const IMathObject &lhs, const IMathObject &rhs) {
return lhs.equalsAbstract(rhs);
Expand Down
2 changes: 1 addition & 1 deletion include/fintamath/core/IMathObjectCRTP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class IMathObjectCRTP_ : public IMathObject {
return equals(cast<Derived>(rhs));
}

MathObjectClass getClass() const override {
MathObjectClass getClass() const noexcept override {
return Derived::getClassStatic();
}

Expand Down
39 changes: 21 additions & 18 deletions include/fintamath/core/MathObjectBody.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,46 @@
#include <memory>

#include "fintamath/core/MathObjectClass.hpp"
#include "fintamath/core/MathObjectIdStorage.hpp"
#include "fintamath/core/Parser.hpp"

#define FINTAMATH_CLASS_BODY(Class) \
public: \
static constexpr MathObjectClass getClassStatic() { \
return {#Class}; \
} \
\
private:
#define FINTAMATH_CLASS_BODY(Class, Parent) \
public: \
static constexpr MathObjectClass getClassStatic() noexcept { \
return &objClass; \
} \
\
private: \
static constexpr detail::MathObjectClassImpl \
objClass{#Class, Parent::getClassStatic()};

#define FINTAMATH_PARENT_CLASS_BODY(Class) \
FINTAMATH_CLASS_BODY(Class) \
#define FINTAMATH_PARENT_CLASS_BODY(Class, Parent) \
FINTAMATH_CLASS_BODY(Class, Parent) \
\
private: \
using Class##Parser = detail::Parser<std::unique_ptr<Class>>; \
\
static Class##Parser &getParser(); \
static Class##Parser &getParser() noexcept; \
\
public: \
static auto parse(std::string str) { \
static auto parse(std::string str) noexcept { \
return getParser().parse(std::move(str)); \
} \
\
static auto parseFirst(std::string str) { \
static auto parseFirst(std::string str) noexcept { \
return getParser().parseFirst(std::move(str)); \
} \
\
template <std::derived_from<Class> T> \
static void registerType() { \
MathObjectClass::bindTypes<Class, T>(); \
static void registerType() noexcept { \
MathObjectIdStorage::add(T::getClassStatic()); \
getParser().registerType<T>(); \
} \
\
private:

#define FINTAMATH_PARENT_CLASS_IMPLEMENTATION(Class) \
Class::Class##Parser &Class::getParser() { \
static Class##Parser parser; \
return parser; \
#define FINTAMATH_PARENT_CLASS_IMPLEMENTATION(Class) \
Class::Class##Parser &Class::getParser() noexcept { \
static Class##Parser parser; \
return parser; \
}
82 changes: 18 additions & 64 deletions include/fintamath/core/MathObjectClass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,92 +11,46 @@

namespace fintamath {

class MathObjectClass;
namespace detail {

}

template <>
struct std::hash<fintamath::MathObjectClass> {
size_t operator()(const fintamath::MathObjectClass &rhs) const noexcept;
};

namespace fintamath {

class MathObjectClass final {
class MathObjectClassImpl final {
public:
using Name = std::string_view;

using Id = size_t;
using Ptr = const MathObjectClassImpl *;

using Children = std::unordered_set<MathObjectClass>;
public:
constexpr MathObjectClassImpl(const Name inName, const Ptr inParent = nullptr) noexcept
: name(inName),
parent(inParent) {
}

private:
using ClassToIdMap = std::unordered_map<MathObjectClass, Id>;
constexpr MathObjectClassImpl(const MathObjectClassImpl &) noexcept = delete;

using ChildToParentMap = std::unordered_map<MathObjectClass, MathObjectClass>;
constexpr MathObjectClassImpl(MathObjectClassImpl &&) noexcept = delete;

using ParentToChildrenMap = std::unordered_map<MathObjectClass, Children>;
constexpr MathObjectClassImpl &operator=(const MathObjectClassImpl &) noexcept = delete;

public:
constexpr MathObjectClass(const Name inName) : name(inName) {
}
constexpr MathObjectClassImpl &operator=(MathObjectClassImpl &&) noexcept = delete;

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

constexpr bool operator==(const MathObjectClass rhs) const {
return name == rhs.name;
constexpr Ptr getParent() const noexcept {
return parent;
}

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

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

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

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

private:
Id getId() const;

static ClassToIdMap &getClassToIdMap();

static ChildToParentMap &getChildToParentMap();

static ParentToChildrenMap &getParentToChildrenMap();

static ParentToChildrenMap &getParentToRecursiveChildrenMap();

private:
Name name;

inline static Id maxId = 0;
Ptr parent;

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

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

getClassToIdMap()[parent] = ++maxId;
getClassToIdMap()[child] = ++maxId;

getChildToParentMap().insert_or_assign(child, parent);
getParentToChildrenMap()[parent].emplace(child);

for (std::optional superParent = child.getParent(); superParent; superParent = superParent->getParent()) {
Children &superParentChildren = getParentToRecursiveChildrenMap()[*superParent];
superParentChildren.emplace(child);
superParentChildren.insert(child.getChildren().begin(), child.getChildren().end());
}
}

}
using MathObjectClass = detail::MathObjectClassImpl::Ptr;

inline size_t std::hash<fintamath::MathObjectClass>::operator()(const fintamath::MathObjectClass &rhs) const noexcept {
return std::hash<fintamath::MathObjectClass::Name>{}(rhs.getName());
}
24 changes: 24 additions & 0 deletions include/fintamath/core/MathObjectIdStorage.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include <unordered_map>

#include "fintamath/core/MathObjectClass.hpp"

namespace fintamath {

class MathObjectIdStorage {
using MathObjectClassToIdMap = std::unordered_map<MathObjectClass, size_t>;

public:
static size_t get(MathObjectClass objClass) noexcept;

static void add(MathObjectClass objClass) noexcept;

private:
static MathObjectClassToIdMap &getMap() noexcept;

private:
static inline size_t maxId = 1;
};

}
Loading

0 comments on commit 11028e6

Please sign in to comment.