diff --git a/poincare/src/bracket_pair_layout_node.cpp b/poincare/src/bracket_pair_layout_node.cpp index b92589d1f..577d1d9ce 100644 --- a/poincare/src/bracket_pair_layout_node.cpp +++ b/poincare/src/bracket_pair_layout_node.cpp @@ -73,8 +73,18 @@ void BracketPairLayoutNode::moveCursorRight(LayoutCursor * cursor, bool * should void BracketPairLayoutNode::deleteBeforeCursor(LayoutCursor * cursor) { if (cursor->isEquivalentTo(LayoutCursor(childLayout(), LayoutCursor::Position::Left))) { // Case: Left of the operand. Delete the layout, keep the operand. - LayoutRef(this).replaceWith(LayoutRef(childLayout()), cursor); + LayoutRef rootRef = LayoutRef(root()); + LayoutRef thisRef = LayoutRef(this); + LayoutRef child = childLayout(); + replaceChildWithGhostInPlace(child); // WARNING: do not call "this" afterwards + if (rootRef.isAllocationFailure()) { + cursor->setLayoutReference(rootRef); + return; + } + cursor->setLayoutReference(thisRef.childAtIndex(0)); + cursor->setPosition(LayoutNode::Position::Left); + thisRef.replaceWith(child, cursor); return; } LayoutNode::deleteBeforeCursor(cursor); diff --git a/poincare/src/fraction_layout_node.cpp b/poincare/src/fraction_layout_node.cpp index 120d1e014..f1d5d0614 100644 --- a/poincare/src/fraction_layout_node.cpp +++ b/poincare/src/fraction_layout_node.cpp @@ -109,16 +109,10 @@ void FractionLayoutNode::deleteBeforeCursor(LayoutCursor * cursor) { * is right of the numerator. */ LayoutRef numeratorRef = LayoutRef(numeratorLayout()); LayoutRef denominatorRef = LayoutRef(denominatorLayout()); - thisRef.replaceChild(numeratorRef, EmptyLayoutRef()); - if (thisRef.isAllocationFailure()) { - return; - } - thisRef.replaceChild(denominatorRef, EmptyLayoutRef()); - if (thisRef.isAllocationFailure()) { - return; - } - thisRef.replaceWithJuxtapositionOf(numeratorRef, denominatorRef, cursor, true); + thisRef.replaceChildWithGhostInPlace(numeratorRef); // WARNING: Do no use "this" afterwards + thisRef.replaceChildWithGhostInPlace(denominatorRef); + thisRef.replaceWithJuxtapositionOf(numeratorRef, denominatorRef, cursor, true); return; } diff --git a/poincare/src/integral_layout_node.cpp b/poincare/src/integral_layout_node.cpp index 6e6f55e1c..d4603fdcf 100644 --- a/poincare/src/integral_layout_node.cpp +++ b/poincare/src/integral_layout_node.cpp @@ -132,8 +132,18 @@ void IntegralLayoutNode::moveCursorDown(LayoutCursor * cursor, bool * shouldReco void IntegralLayoutNode::deleteBeforeCursor(LayoutCursor * cursor) { if (cursor->isEquivalentTo(LayoutCursor(integrandLayout(), LayoutCursor::Position::Left))) { // Case: Left of the integrand. Delete the layout, keep the integrand. - LayoutRef(this).replaceWith(LayoutRef(integrandLayout()), cursor); + LayoutRef rootRef = LayoutRef(root()); + LayoutRef thisRef = LayoutRef(this); + LayoutRef integrand = LayoutRef(integrandLayout()); + thisRef.replaceChildWithGhostInPlace(integrand); // WARNING: Do not use "this" afterwards + if (rootRef.isAllocationFailure()) { + cursor->setLayoutReference(rootRef); + return; + } + cursor->setLayoutReference(thisRef.childAtIndex(0)); + cursor->setPosition(LayoutCursor::Position::Left); + thisRef.replaceWith(integrand, cursor); return; } LayoutNode::deleteBeforeCursor(cursor); diff --git a/poincare/src/nth_root_layout_node.cpp b/poincare/src/nth_root_layout_node.cpp index 3513fec5a..c0a76b891 100644 --- a/poincare/src/nth_root_layout_node.cpp +++ b/poincare/src/nth_root_layout_node.cpp @@ -139,8 +139,17 @@ void NthRootLayoutNode::deleteBeforeCursor(LayoutCursor * cursor) { && cursor->position() == LayoutCursor::Position::Left) { // Case: Left of the radicand. Delete the layout, keep the radicand. - NthRootLayoutRef(this).replaceWith(LayoutRef(radicandLayout()), cursor); + LayoutRef radicand = LayoutRef(radicandLayout()); + LayoutRef thisRef = LayoutRef(this); + LayoutRef rootRef = LayoutRef(root()); + thisRef.replaceChildWithGhostInPlace(radicand); // WARNING: Do not call "this" afterwards + if (rootRef.isAllocationFailure()) { + cursor->setLayoutReference(rootRef); + return; + } + cursor->setLayoutReference(thisRef.childAtIndex(0)); + thisRef.replaceWith(radicand, cursor); return; } LayoutNode::deleteBeforeCursor(cursor); diff --git a/poincare/src/sequence_layout_node.cpp b/poincare/src/sequence_layout_node.cpp index 688bcc5fe..a81891e4c 100644 --- a/poincare/src/sequence_layout_node.cpp +++ b/poincare/src/sequence_layout_node.cpp @@ -119,8 +119,17 @@ void SequenceLayoutNode::moveCursorDown(LayoutCursor * cursor, bool * shouldReco void SequenceLayoutNode::deleteBeforeCursor(LayoutCursor * cursor) { if (cursor->isEquivalentTo(LayoutCursor(argumentLayout(), LayoutCursor::Position::Left))) { // Case: Left of the argument. Delete the layout, keep the argument. - LayoutRef(this).replaceWith(LayoutRef(argumentLayout()), cursor); - // WARNING: do not use "this" afterwards + LayoutRef argument = LayoutRef(argumentLayout()); + LayoutRef thisRef = LayoutRef(this); + LayoutRef rootRef = LayoutRef(root()); + thisRef.replaceChildWithGhostInPlace(argument); + // WARNING: Do not call "this" afterwards + if (rootRef.isAllocationFailure()) { + cursor->setLayoutReference(rootRef); + return; + } + cursor->setLayoutReference(thisRef.childAtIndex(0)); + thisRef.replaceWith(argument, cursor); return; } LayoutNode::deleteBeforeCursor(cursor); diff --git a/poincare/src/tree_by_reference.cpp b/poincare/src/tree_by_reference.cpp index e59129e6f..971618ea8 100644 --- a/poincare/src/tree_by_reference.cpp +++ b/poincare/src/tree_by_reference.cpp @@ -32,6 +32,9 @@ TreeByReference TreeByReference::clone() const { void TreeByReference::replaceWithInPlace(TreeByReference t) { assert(isDefined()); + if (isAllocationFailure()) { + return; + } TreeByReference p = parent(); if (p.isDefined()) { p.replaceChildInPlace(*this, t); @@ -44,6 +47,9 @@ void TreeByReference::replaceChildInPlace(TreeByReference oldChild, TreeByRefere } assert(isDefined()); + if (isAllocationFailure()) { + return; + } if (newChild.isAllocationFailure()) { replaceWithAllocationFailureInPlace(numberOfChildren()); return;