mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[poincare] TreeNode::parent() should never return nullptr
This commit is contained in:
@@ -32,6 +32,9 @@ public:
|
||||
virtual Expression complexToExpression(Preferences::ComplexFormat complexFormat) const = 0;
|
||||
virtual std::complex<T> trace() const = 0;
|
||||
virtual std::complex<T> determinant() const = 0;
|
||||
|
||||
// TreeNode
|
||||
TreeNode * uninitializedStaticNode() const override;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
||||
@@ -153,6 +153,10 @@ public:
|
||||
|
||||
/* Hierarchy */
|
||||
ExpressionNode * childAtIndex(int i) const override { return static_cast<ExpressionNode *>(TreeNode::childAtIndex(i)); }
|
||||
|
||||
|
||||
// TreeNode
|
||||
TreeNode * uninitializedStaticNode() const override;
|
||||
protected:
|
||||
// Private methods used in simplification process
|
||||
/*!*/ virtual Expression denominator(Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
|
||||
@@ -21,14 +21,33 @@ public:
|
||||
// Allocation Failure
|
||||
static GhostNode * FailedAllocationStaticNode();
|
||||
TreeNode * failedAllocationStaticNode() override { return FailedAllocationStaticNode(); }
|
||||
// Uninitialized
|
||||
TreeNode * uninitializedStaticNode() const override;
|
||||
};
|
||||
|
||||
class UninitializedGhostNode : public GhostNode {
|
||||
public:
|
||||
static UninitializedGhostNode * UninitializedGhostStaticNode();
|
||||
|
||||
size_t size() const override { return sizeof(UninitializedGhostNode); }
|
||||
bool isUninitialized() const override { return true; }
|
||||
GhostNode * failedAllocationStaticNode() override { assert(false); return nullptr; } //TODO ?
|
||||
int numberOfChildren() const override { return 0; }
|
||||
#if POINCARE_TREE_LOG
|
||||
virtual void logNodeName(std::ostream & stream) const override {
|
||||
stream << "UninitializedGhost";
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
class AllocationFailedGhostNode : public GhostNode {
|
||||
public:
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(AllocationFailedGhostNode); }
|
||||
#if TREE_LOG
|
||||
const char * description() const override { return "AllocationFailedGhost"; }
|
||||
#if POINCARE_TREE_LOG
|
||||
virtual void logNodeName(std::ostream & stream) const override {
|
||||
stream << "AllocationFailedGhost";
|
||||
}
|
||||
#endif
|
||||
bool isAllocationFailure() const override { return true; }
|
||||
};
|
||||
|
||||
@@ -129,6 +129,10 @@ public:
|
||||
virtual void didReplaceChildAtIndex(int index, LayoutCursor * cursor, bool force) {}
|
||||
virtual bool willRemoveChild(LayoutNode * l, LayoutCursor * cursor, bool force);
|
||||
virtual void didRemoveChildAtIndex(int index, LayoutCursor * cursor, bool force) {}
|
||||
|
||||
// TreeNode
|
||||
TreeNode * uninitializedStaticNode() const override;
|
||||
|
||||
protected:
|
||||
// Tree navigation
|
||||
virtual void moveCursorVertically(VerticalDirection direction, LayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited);
|
||||
|
||||
@@ -38,6 +38,7 @@ public:
|
||||
|
||||
// Uninitialized node
|
||||
virtual bool isUninitialized() const { return false; }
|
||||
virtual TreeNode * uninitializedStaticNode() const = 0;
|
||||
|
||||
// Ghost
|
||||
virtual bool isGhost() const { return false; }
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
template<typename T>
|
||||
TreeNode * EvaluationNode<T>::uninitializedStaticNode() const {
|
||||
return Evaluation<T>().node();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Evaluation<T>::Evaluation() : Evaluation<T>(UninitializedEvaluationNode<T>::UninitializedEvaluationStaticNode()) {}
|
||||
|
||||
@@ -12,6 +17,8 @@ Expression Evaluation<T>::complexToExpression(Preferences::ComplexFormat complex
|
||||
return node()->complexToExpression(complexFormat);
|
||||
}
|
||||
|
||||
template TreeNode * EvaluationNode<float>::uninitializedStaticNode() const;
|
||||
template TreeNode * EvaluationNode<double>::uninitializedStaticNode() const;
|
||||
template Evaluation<float>::Evaluation();
|
||||
template Evaluation<double>::Evaluation();
|
||||
template Expression Evaluation<float>::complexToExpression(Preferences::ComplexFormat) const;
|
||||
|
||||
@@ -93,6 +93,10 @@ bool ExpressionNode::isOfType(Type * types, int length) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
TreeNode * ExpressionNode::uninitializedStaticNode() const {
|
||||
return Expression().node();
|
||||
}
|
||||
|
||||
Expression ExpressionNode::denominator(Context & context, Preferences::AngleUnit angleUnit) const {
|
||||
return Expression();
|
||||
}
|
||||
|
||||
@@ -3,10 +3,20 @@
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
TreeNode * GhostNode::uninitializedStaticNode() const {
|
||||
return UninitializedGhostNode::UninitializedGhostStaticNode();
|
||||
}
|
||||
|
||||
GhostNode * GhostNode::FailedAllocationStaticNode() {
|
||||
static AllocationFailedGhostNode failure;
|
||||
TreePool::sharedPool()->registerStaticNodeIfRequired(&failure);
|
||||
return &failure;
|
||||
}
|
||||
|
||||
UninitializedGhostNode * UninitializedGhostNode::UninitializedGhostStaticNode() {
|
||||
static UninitializedGhostNode exception;
|
||||
TreePool::sharedPool()->registerStaticNodeIfRequired(&exception);
|
||||
return &exception;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -144,6 +144,12 @@ bool LayoutNode::canBeOmittedMultiplicationRightFactor() const {
|
||||
return isCollapsable(&numberOfOpenParentheses, false) && !isVerticalOffset();
|
||||
}
|
||||
|
||||
// TreeNode
|
||||
|
||||
TreeNode * LayoutNode::uninitializedStaticNode() const {
|
||||
return LayoutReference().node();
|
||||
}
|
||||
|
||||
// Private
|
||||
|
||||
void LayoutNode::moveCursorVertically(VerticalDirection direction, LayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
|
||||
|
||||
@@ -38,7 +38,7 @@ void TreeNode::rename(int identifier, bool unregisterPreviousIdentifier) {
|
||||
|
||||
TreeNode * TreeNode::parent() const {
|
||||
if (isStatic()) {
|
||||
return nullptr;
|
||||
return uninitializedStaticNode();
|
||||
}
|
||||
/* Choose between these algorithms: the first has complexity O(numberNodes)
|
||||
* but uses O(3maxNumberNodes) space. The second is much clearer for the
|
||||
|
||||
@@ -2,10 +2,20 @@
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
TreeNode * BlobNode::uninitializedStaticNode() const {
|
||||
return UninitializedBlobNode::UninitializedBlobStaticNode();
|
||||
}
|
||||
|
||||
BlobNode * BlobNode::FailedAllocationStaticNode() {
|
||||
static AllocationFailureBlobNode failureNode;
|
||||
TreePool::sharedPool()->registerStaticNodeIfRequired(&failureNode);
|
||||
return &failureNode;
|
||||
}
|
||||
|
||||
UninitializedBlobNode * UninitializedBlobNode::UninitializedBlobStaticNode() {
|
||||
static UninitializedBlobNode exception;
|
||||
TreePool::sharedPool()->registerStaticNodeIfRequired(&exception);
|
||||
return &exception;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ public:
|
||||
virtual BlobNode * failedAllocationStaticNode() override {
|
||||
return BlobNode::FailedAllocationStaticNode();
|
||||
}
|
||||
TreeNode * uninitializedStaticNode() const override;
|
||||
|
||||
virtual size_t size() const override { return sizeof(BlobNode); }
|
||||
int data() { return m_data; }
|
||||
void setData(int data) { m_data = data; }
|
||||
@@ -26,6 +28,21 @@ private:
|
||||
int m_data;
|
||||
};
|
||||
|
||||
class UninitializedBlobNode : public BlobNode {
|
||||
public:
|
||||
static UninitializedBlobNode * UninitializedBlobStaticNode();
|
||||
|
||||
size_t size() const override { return sizeof(UninitializedBlobNode); }
|
||||
bool isUninitialized() const override { return true; }
|
||||
BlobNode * failedAllocationStaticNode() override { assert(false); return nullptr; } //TODO ?
|
||||
int numberOfChildren() const override { return 0; }
|
||||
#if POINCARE_TREE_LOG
|
||||
virtual void logNodeName(std::ostream & stream) const override {
|
||||
stream << "UninitializedBlob";
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
class AllocationFailureBlobNode : public BlobNode {
|
||||
size_t size() const override { return sizeof(AllocationFailureBlobNode); }
|
||||
bool isAllocationFailure() const override { return true; }
|
||||
|
||||
@@ -2,10 +2,20 @@
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
TreeNode * PairNode::uninitializedStaticNode() const {
|
||||
return UninitializedPairNode::UninitializedPairStaticNode();
|
||||
}
|
||||
|
||||
PairNode * PairNode::FailedAllocationStaticNode() {
|
||||
static AllocationFailurePairNode failureNode;
|
||||
TreePool::sharedPool()->registerStaticNodeIfRequired(&failureNode);
|
||||
return &failureNode;
|
||||
}
|
||||
|
||||
UninitializedPairNode * UninitializedPairNode::UninitializedPairStaticNode() {
|
||||
static UninitializedPairNode exception;
|
||||
TreePool::sharedPool()->registerStaticNodeIfRequired(&exception);
|
||||
return &exception;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ public:
|
||||
virtual PairNode * failedAllocationStaticNode() override {
|
||||
return PairNode::FailedAllocationStaticNode();
|
||||
}
|
||||
TreeNode * uninitializedStaticNode() const override;
|
||||
|
||||
virtual size_t size() const override { return sizeof(PairNode); }
|
||||
virtual int numberOfChildren() const override { return 2; }
|
||||
#if POINCARE_TREE_LOG
|
||||
@@ -22,6 +24,21 @@ public:
|
||||
#endif
|
||||
};
|
||||
|
||||
class UninitializedPairNode : public PairNode {
|
||||
public:
|
||||
static UninitializedPairNode * UninitializedPairStaticNode();
|
||||
|
||||
size_t size() const override { return sizeof(UninitializedPairNode); }
|
||||
bool isUninitialized() const override { return true; }
|
||||
PairNode * failedAllocationStaticNode() override { assert(false); return nullptr; } //TODO ?
|
||||
int numberOfChildren() const override { return 0; }
|
||||
#if POINCARE_TREE_LOG
|
||||
virtual void logNodeName(std::ostream & stream) const override {
|
||||
stream << "UninitializedPairNode";
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
class AllocationFailurePairNode : public PairNode {
|
||||
size_t size() const override { return sizeof(AllocationFailurePairNode); }
|
||||
bool isAllocationFailure() const override { return true; }
|
||||
|
||||
Reference in New Issue
Block a user