From 7b5f3c570d45c848a1b13deacfd97c911b99ef9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Mon, 18 Feb 2019 11:37:22 +0100 Subject: [PATCH] [poincare] Change the way Expression are built --- apps/calculation/calculation.cpp | 4 +- apps/calculation/calculation_store.cpp | 2 +- apps/regression/calculation_controller.cpp | 2 +- apps/regression/model/cubic_model.cpp | 40 +-- apps/regression/model/exponential_model.cpp | 12 +- apps/regression/model/linear_model.cpp | 10 +- apps/regression/model/logarithmic_model.cpp | 18 +- apps/regression/model/logistic_model.cpp | 20 +- apps/regression/model/power_model.cpp | 8 +- apps/regression/model/quadratic_model.cpp | 26 +- apps/regression/model/quartic_model.cpp | 54 +-- apps/regression/model/trigonometric_model.cpp | 30 +- apps/regression/regression_context.cpp | 2 +- apps/sequence/cache_context.cpp | 2 +- apps/sequence/graph/term_sum_controller.cpp | 4 +- apps/sequence/list/sequence_toolbox.cpp | 6 +- .../list/type_parameter_controller.cpp | 2 +- apps/sequence/sequence.cpp | 22 +- .../sub_menu/preferences_controller.cpp | 2 +- apps/shared/global_context.cpp | 2 +- apps/shared/storage_cartesian_function.cpp | 4 +- apps/shared/storage_expression_model.cpp | 2 +- apps/shared/storage_sum_graph_controller.cpp | 2 +- apps/shared/sum_graph_controller.cpp | 2 +- apps/solver/equation.cpp | 6 +- apps/solver/equation_store.cpp | 50 +-- apps/solver/solutions_controller.cpp | 2 +- apps/statistics/statistics_context.cpp | 2 +- poincare/Makefile | 2 + poincare/include/poincare/absolute_value.h | 7 +- .../include/poincare/absolute_value_layout.h | 9 +- poincare/include/poincare/addition.h | 14 +- poincare/include/poincare/arc_cosine.h | 6 +- poincare/include/poincare/arc_sine.h | 6 +- poincare/include/poincare/arc_tangent.h | 6 +- .../include/poincare/binomial_coefficient.h | 6 +- .../poincare/binomial_coefficient_layout.h | 11 +- poincare/include/poincare/ceiling.h | 6 +- poincare/include/poincare/ceiling_layout.h | 7 +- poincare/include/poincare/char_layout.h | 4 +- poincare/include/poincare/complex.h | 11 +- poincare/include/poincare/complex_argument.h | 6 +- poincare/include/poincare/complex_cartesian.h | 8 +- .../include/poincare/condensed_sum_layout.h | 11 +- .../include/poincare/confidence_interval.h | 13 +- poincare/include/poincare/conjugate.h | 6 +- poincare/include/poincare/conjugate_layout.h | 7 +- poincare/include/poincare/constant.h | 4 +- poincare/include/poincare/cosine.h | 6 +- poincare/include/poincare/decimal.h | 23 +- poincare/include/poincare/derivative.h | 9 +- poincare/include/poincare/determinant.h | 6 +- poincare/include/poincare/division.h | 12 +- poincare/include/poincare/division_quotient.h | 7 +- .../include/poincare/division_remainder.h | 7 +- poincare/include/poincare/empty_expression.h | 2 +- poincare/include/poincare/empty_layout.h | 4 +- poincare/include/poincare/equal.h | 5 +- poincare/include/poincare/factor.h | 6 +- poincare/include/poincare/factorial.h | 9 +- poincare/include/poincare/float.h | 8 +- poincare/include/poincare/floor.h | 6 +- poincare/include/poincare/floor_layout.h | 7 +- poincare/include/poincare/frac_part.h | 6 +- poincare/include/poincare/fraction_layout.h | 10 +- poincare/include/poincare/function.h | 9 +- poincare/include/poincare/ghost.h | 9 +- .../include/poincare/great_common_divisor.h | 7 +- poincare/include/poincare/grid_layout.h | 3 +- poincare/include/poincare/horizontal_layout.h | 3 +- .../include/poincare/hyperbolic_arc_cosine.h | 6 +- .../include/poincare/hyperbolic_arc_sine.h | 6 +- .../include/poincare/hyperbolic_arc_tangent.h | 6 +- poincare/include/poincare/hyperbolic_cosine.h | 6 +- poincare/include/poincare/hyperbolic_sine.h | 6 +- .../include/poincare/hyperbolic_tangent.h | 6 +- poincare/include/poincare/imaginary_part.h | 8 +- poincare/include/poincare/infinity.h | 6 +- poincare/include/poincare/integer.h | 3 +- poincare/include/poincare/integral.h | 10 +- poincare/include/poincare/integral_layout.h | 12 +- .../include/poincare/least_common_multiple.h | 7 +- .../poincare/left_parenthesis_layout.h | 5 +- .../poincare/left_square_bracket_layout.h | 5 +- poincare/include/poincare/logarithm.h | 14 +- poincare/include/poincare/matrix.h | 3 +- poincare/include/poincare/matrix_complex.h | 4 +- poincare/include/poincare/matrix_dimension.h | 6 +- poincare/include/poincare/matrix_inverse.h | 6 +- poincare/include/poincare/matrix_layout.h | 3 +- poincare/include/poincare/matrix_trace.h | 6 +- poincare/include/poincare/matrix_transpose.h | 6 +- poincare/include/poincare/multiplication.h | 18 +- .../include/poincare/naperian_logarithm.h | 8 +- poincare/include/poincare/nth_root.h | 7 +- poincare/include/poincare/nth_root_layout.h | 26 +- poincare/include/poincare/opposite.h | 12 +- poincare/include/poincare/parenthesis.h | 7 +- .../include/poincare/permute_coefficient.h | 8 +- poincare/include/poincare/power.h | 8 +- .../include/poincare/prediction_interval.h | 7 +- poincare/include/poincare/product.h | 10 +- poincare/include/poincare/product_layout.h | 12 +- poincare/include/poincare/randint.h | 7 +- poincare/include/poincare/random.h | 3 +- poincare/include/poincare/rational.h | 24 +- poincare/include/poincare/real_part.h | 8 +- .../poincare/right_parenthesis_layout.h | 5 +- .../poincare/right_square_bracket_layout.h | 6 +- poincare/include/poincare/round.h | 7 +- poincare/include/poincare/sign_function.h | 6 +- poincare/include/poincare/sine.h | 6 +- poincare/include/poincare/square_root.h | 5 +- poincare/include/poincare/store.h | 8 +- poincare/include/poincare/subtraction.h | 13 +- poincare/include/poincare/sum.h | 10 +- poincare/include/poincare/sum_layout.h | 12 +- poincare/include/poincare/symbol.h | 10 +- poincare/include/poincare/symbol_abstract.h | 2 - poincare/include/poincare/tangent.h | 6 +- poincare/include/poincare/tree_handle.h | 3 + poincare/include/poincare/tree_node.h | 1 - poincare/include/poincare/tree_pool.h | 6 +- poincare/include/poincare/undefined.h | 2 +- poincare/include/poincare/unreal.h | 3 +- .../include/poincare/vertical_offset_layout.h | 12 +- poincare/src/absolute_value.cpp | 9 +- poincare/src/absolute_value_layout.cpp | 12 + poincare/src/addition.cpp | 25 +- poincare/src/approximation_helper.cpp | 6 +- poincare/src/arc_cosine.cpp | 9 +- poincare/src/arc_sine.cpp | 9 +- poincare/src/arc_tangent.cpp | 9 +- poincare/src/binomial_coefficient.cpp | 27 +- poincare/src/binomial_coefficient_layout.cpp | 8 + poincare/src/ceiling.cpp | 17 +- poincare/src/ceiling_layout.cpp | 7 + poincare/src/char_layout.cpp | 10 +- poincare/src/complex.cpp | 26 +- poincare/src/complex_argument.cpp | 15 +- poincare/src/complex_cartesian.cpp | 64 ++-- poincare/src/condensed_sum_layout.cpp | 9 +- poincare/src/confidence_interval.cpp | 26 +- poincare/src/conjugate.cpp | 11 +- poincare/src/conjugate_layout.cpp | 7 + poincare/src/constant.cpp | 21 +- poincare/src/cosine.cpp | 9 +- poincare/src/decimal.cpp | 44 ++- poincare/src/derivative.cpp | 13 +- poincare/src/determinant.cpp | 9 +- poincare/src/division.cpp | 18 +- poincare/src/division_quotient.cpp | 19 +- poincare/src/division_remainder.cpp | 19 +- poincare/src/empty_expression.cpp | 9 +- poincare/src/empty_layout.cpp | 13 +- poincare/src/equal.cpp | 11 +- poincare/src/expression.cpp | 38 +- poincare/src/factor.cpp | 19 +- poincare/src/factorial.cpp | 19 +- poincare/src/float.cpp | 13 +- poincare/src/floor.cpp | 15 +- poincare/src/floor_layout.cpp | 12 + poincare/src/frac_part.cpp | 11 +- poincare/src/fraction_layout.cpp | 11 +- poincare/src/function.cpp | 21 +- poincare/src/great_common_divisor.cpp | 18 +- poincare/src/grid_layout.cpp | 11 +- poincare/src/horizontal_layout.cpp | 9 +- poincare/src/hyperbolic_arc_cosine.cpp | 9 +- poincare/src/hyperbolic_arc_sine.cpp | 9 +- poincare/src/hyperbolic_arc_tangent.cpp | 9 +- poincare/src/hyperbolic_cosine.cpp | 9 +- poincare/src/hyperbolic_sine.cpp | 9 +- poincare/src/hyperbolic_tangent.cpp | 9 +- poincare/src/imaginary_part.cpp | 9 +- poincare/src/infinity.cpp | 11 +- poincare/src/integer.cpp | 33 +- poincare/src/integral.cpp | 12 +- poincare/src/integral_layout.cpp | 7 + poincare/src/layout.cpp | 2 +- poincare/src/layout_cursor.cpp | 38 +- poincare/src/layout_helper.cpp | 4 +- poincare/src/least_common_multiple.cpp | 19 +- poincare/src/left_parenthesis_layout.cpp | 7 + poincare/src/left_square_bracket_layout.cpp | 7 + poincare/src/logarithm.cpp | 55 +-- poincare/src/matrix.cpp | 25 +- poincare/src/matrix_complex.cpp | 31 +- poincare/src/matrix_dimension.cpp | 21 +- poincare/src/matrix_inverse.cpp | 15 +- poincare/src/matrix_layout.cpp | 7 + poincare/src/matrix_trace.cpp | 13 +- poincare/src/matrix_transpose.cpp | 7 + poincare/src/multiplication.cpp | 41 ++- poincare/src/naperian_logarithm.cpp | 9 +- poincare/src/nth_root.cpp | 13 +- poincare/src/nth_root_layout.cpp | 14 + poincare/src/number.cpp | 22 +- poincare/src/opposite.cpp | 17 +- poincare/src/parenthesis.cpp | 7 + poincare/src/parsing/parser.cpp | 24 +- poincare/src/permute_coefficient.cpp | 23 +- poincare/src/power.cpp | 131 +++---- poincare/src/prediction_interval.cpp | 25 +- poincare/src/product.cpp | 9 +- poincare/src/product_layout.cpp | 7 + poincare/src/randint.cpp | 9 +- poincare/src/random.cpp | 9 +- poincare/src/rational.cpp | 73 ++-- poincare/src/real_part.cpp | 7 + poincare/src/right_parenthesis_layout.cpp | 7 + poincare/src/right_square_bracket_layout.cpp | 7 + poincare/src/round.cpp | 19 +- poincare/src/sequence.cpp | 2 +- poincare/src/sign_function.cpp | 25 +- poincare/src/sine.cpp | 9 +- poincare/src/square_root.cpp | 11 +- poincare/src/store.cpp | 15 +- poincare/src/subtraction.cpp | 18 +- poincare/src/sum.cpp | 9 +- poincare/src/sum_layout.cpp | 7 + poincare/src/symbol.cpp | 33 +- poincare/src/symbol_abstract.cpp | 18 +- poincare/src/tangent.cpp | 9 +- poincare/src/tree_handle.cpp | 26 ++ poincare/src/tree_pool.cpp | 127 ------- poincare/src/trigonometry.cpp | 30 +- poincare/src/undefined.cpp | 7 + poincare/src/unreal.cpp | 6 + poincare/src/variable_context.cpp | 2 +- poincare/src/vertical_offset_layout.cpp | 7 + poincare/test/addition.cpp | 12 +- poincare/test/convert_expression_to_text.cpp | 112 +++--- poincare/test/decimal.cpp | 36 +- poincare/test/expression.cpp | 2 +- poincare/test/expression_order.cpp | 50 +-- poincare/test/float.cpp | 40 +-- poincare/test/fraction_layout.cpp | 10 +- poincare/test/layouts.cpp | 198 +++++----- poincare/test/number.cpp | 30 +- poincare/test/parentheses_layout.cpp | 12 +- poincare/test/parser.cpp | 338 +++++++++--------- poincare/test/properties.cpp | 24 +- poincare/test/rational.cpp | 78 ++-- poincare/test/tree/blob_node.h | 10 +- poincare/test/tree/pair_node.h | 11 +- poincare/test/tree/tree_handle.cpp | 24 +- poincare/test/user_variable.cpp | 16 +- poincare/test/vertical_offset_layout.cpp | 2 +- 249 files changed, 2076 insertions(+), 1908 deletions(-) create mode 100644 poincare/src/absolute_value_layout.cpp create mode 100644 poincare/src/floor_layout.cpp diff --git a/apps/calculation/calculation.cpp b/apps/calculation/calculation.cpp index e794cbf30..1bf479107 100644 --- a/apps/calculation/calculation.cpp +++ b/apps/calculation/calculation.cpp @@ -125,7 +125,7 @@ Expression Calculation::exactOutput() { * 'cos(pi/4) = 0.999906' (which is true in degree). */ Expression exactOutput = Expression::Parse(m_exactOutputText); if (exactOutput.isUninitialized()) { - return Undefined(); + return Undefined::Builder(); } return exactOutput; } @@ -178,7 +178,7 @@ Calculation::EqualSign Calculation::exactAndApproximateDisplayedOutputsAreEqual( Preferences * preferences = Preferences::sharedPreferences(); Expression exactOutputExpression = PoincareHelpers::ParseAndSimplify(m_exactOutputText, *context); if (exactOutputExpression.isUninitialized()) { - exactOutputExpression = Undefined(); + exactOutputExpression = Undefined::Builder(); } Preferences::ComplexFormat complexFormat = Expression::UpdatedComplexFormatWithTextInput(preferences->complexFormat(), m_inputText); m_equalSign = exactOutputExpression.isEqualToItsApproximationLayout(approximateOutput(context), buffer, bufferSize, complexFormat, preferences->angleUnit(), preferences->displayMode(), preferences->numberOfSignificantDigits(), *context) ? EqualSign::Equal : EqualSign::Approximation; diff --git a/apps/calculation/calculation_store.cpp b/apps/calculation/calculation_store.cpp index 64813e188..d235445d1 100644 --- a/apps/calculation/calculation_store.cpp +++ b/apps/calculation/calculation_store.cpp @@ -88,7 +88,7 @@ void CalculationStore::tidy() { Expression CalculationStore::ansExpression(Context * context) { if (numberOfCalculations() == 0) { - return Rational(0); + return Rational::Builder(0); } Calculation * lastCalculation = calculationAtIndex(numberOfCalculations()-1); /* Special case: the exact output is a Store/Equal expression. diff --git a/apps/regression/calculation_controller.cpp b/apps/regression/calculation_controller.cpp index 3b21ba53f..895256377 100644 --- a/apps/regression/calculation_controller.cpp +++ b/apps/regression/calculation_controller.cpp @@ -25,7 +25,7 @@ CalculationController::CalculationController(Responder * parentResponder, Button m_hideableCell(), m_store(store) { - m_r2Layout = HorizontalLayout::Builder(CharLayout('r', KDFont::SmallFont), VerticalOffsetLayout::Builder(CharLayout('2', KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Superscript)); + m_r2Layout = HorizontalLayout::Builder(CharLayout::Builder('r', KDFont::SmallFont), VerticalOffsetLayout::Builder(CharLayout::Builder('2', KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Superscript)); m_selectableTableView.setVerticalCellOverlap(0); m_selectableTableView.setBackgroundColor(Palette::WallScreenDark); m_selectableTableView.setMargins(k_margin, k_scrollBarMargin, k_scrollBarMargin, k_margin); diff --git a/apps/regression/model/cubic_model.cpp b/apps/regression/model/cubic_model.cpp index 1452ccf53..da7fc39c6 100644 --- a/apps/regression/model/cubic_model.cpp +++ b/apps/regression/model/cubic_model.cpp @@ -20,27 +20,27 @@ namespace Regression { Layout CubicModel::layout() { if (m_layout.isUninitialized()) { const Layout layoutChildren[] = { - CharLayout('a', KDFont::SmallFont), - CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont), - CharLayout('X', KDFont::SmallFont), + CharLayout::Builder('a', KDFont::SmallFont), + CharLayout::Builder(Ion::Charset::MiddleDot, KDFont::SmallFont), + CharLayout::Builder('X', KDFont::SmallFont), VerticalOffsetLayout::Builder( - CharLayout('3', KDFont::SmallFont), + CharLayout::Builder('3', KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Superscript ), - CharLayout('+', KDFont::SmallFont), - CharLayout('b', KDFont::SmallFont), - CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont), - CharLayout('X', KDFont::SmallFont), + CharLayout::Builder('+', KDFont::SmallFont), + CharLayout::Builder('b', KDFont::SmallFont), + CharLayout::Builder(Ion::Charset::MiddleDot, KDFont::SmallFont), + CharLayout::Builder('X', KDFont::SmallFont), VerticalOffsetLayout::Builder( - CharLayout('2', KDFont::SmallFont), + CharLayout::Builder('2', KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Superscript ), - CharLayout('+', KDFont::SmallFont), - CharLayout('c', KDFont::SmallFont), - CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont), - CharLayout('X', KDFont::SmallFont), - CharLayout('+', KDFont::SmallFont), - CharLayout('d', KDFont::SmallFont), + CharLayout::Builder('+', KDFont::SmallFont), + CharLayout::Builder('c', KDFont::SmallFont), + CharLayout::Builder(Ion::Charset::MiddleDot, KDFont::SmallFont), + CharLayout::Builder('X', KDFont::SmallFont), + CharLayout::Builder('+', KDFont::SmallFont), + CharLayout::Builder('d', KDFont::SmallFont), }; m_layout = HorizontalLayout::Builder(layoutChildren, 15); } @@ -56,16 +56,16 @@ Expression CubicModel::simplifiedExpression(double * modelCoefficients, Poincare Multiplication::Builder( Number::DecimalNumber(a), Power::Builder( - Symbol('x'), - Decimal(3.0))), + Symbol::Builder('x'), + Decimal::Builder(3.0))), Multiplication::Builder( Number::DecimalNumber(b), Power::Builder( - Symbol('x'), - Decimal(2.0))), + Symbol::Builder('x'), + Decimal::Builder(2.0))), Multiplication::Builder( Number::DecimalNumber(c), - Symbol('x')), + Symbol::Builder('x')), Number::DecimalNumber(d) }; // a*x^3+b*x^2+c*x+d diff --git a/apps/regression/model/exponential_model.cpp b/apps/regression/model/exponential_model.cpp index e7097bcf8..52492b4fe 100644 --- a/apps/regression/model/exponential_model.cpp +++ b/apps/regression/model/exponential_model.cpp @@ -12,14 +12,14 @@ namespace Regression { Layout ExponentialModel::layout() { if (m_layout.isUninitialized()) { const Layout layoutChildren[] = { - CharLayout('a', KDFont::SmallFont), - CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont), - CharLayout('e', KDFont::SmallFont), + CharLayout::Builder('a', KDFont::SmallFont), + CharLayout::Builder(Ion::Charset::MiddleDot, KDFont::SmallFont), + CharLayout::Builder('e', KDFont::SmallFont), VerticalOffsetLayout::Builder( HorizontalLayout::Builder( - CharLayout('b', KDFont::SmallFont), - CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont), - CharLayout('X', KDFont::SmallFont) + CharLayout::Builder('b', KDFont::SmallFont), + CharLayout::Builder(Ion::Charset::MiddleDot, KDFont::SmallFont), + CharLayout::Builder('X', KDFont::SmallFont) ), VerticalOffsetLayoutNode::Type::Superscript ) diff --git a/apps/regression/model/linear_model.cpp b/apps/regression/model/linear_model.cpp index 11992808c..272505f6c 100644 --- a/apps/regression/model/linear_model.cpp +++ b/apps/regression/model/linear_model.cpp @@ -12,11 +12,11 @@ namespace Regression { Layout LinearModel::layout() { if (m_layout.isUninitialized()) { const Layout layoutChildren[] = { - CharLayout('a', KDFont::SmallFont), - CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont), - CharLayout('X', KDFont::SmallFont), - CharLayout('+', KDFont::SmallFont), - CharLayout('b', KDFont::SmallFont), + CharLayout::Builder('a', KDFont::SmallFont), + CharLayout::Builder(Ion::Charset::MiddleDot, KDFont::SmallFont), + CharLayout::Builder('X', KDFont::SmallFont), + CharLayout::Builder('+', KDFont::SmallFont), + CharLayout::Builder('b', KDFont::SmallFont), }; m_layout = HorizontalLayout::Builder(layoutChildren, 5); } diff --git a/apps/regression/model/logarithmic_model.cpp b/apps/regression/model/logarithmic_model.cpp index 546f434ea..bb585ea59 100644 --- a/apps/regression/model/logarithmic_model.cpp +++ b/apps/regression/model/logarithmic_model.cpp @@ -12,15 +12,15 @@ namespace Regression { Layout LogarithmicModel::layout() { if (m_layout.isUninitialized()) { const Layout layoutChildren[] = { - CharLayout('a', KDFont::SmallFont), - CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont), - CharLayout('l', KDFont::SmallFont), - CharLayout('n', KDFont::SmallFont), - CharLayout('(', KDFont::SmallFont), - CharLayout('X', KDFont::SmallFont), - CharLayout(')', KDFont::SmallFont), - CharLayout('+', KDFont::SmallFont), - CharLayout('b', KDFont::SmallFont) + CharLayout::Builder('a', KDFont::SmallFont), + CharLayout::Builder(Ion::Charset::MiddleDot, KDFont::SmallFont), + CharLayout::Builder('l', KDFont::SmallFont), + CharLayout::Builder('n', KDFont::SmallFont), + CharLayout::Builder('(', KDFont::SmallFont), + CharLayout::Builder('X', KDFont::SmallFont), + CharLayout::Builder(')', KDFont::SmallFont), + CharLayout::Builder('+', KDFont::SmallFont), + CharLayout::Builder('b', KDFont::SmallFont) }; m_layout = HorizontalLayout::Builder(layoutChildren, 9); } diff --git a/apps/regression/model/logistic_model.cpp b/apps/regression/model/logistic_model.cpp index 79b8d3bdc..c3f91bf95 100644 --- a/apps/regression/model/logistic_model.cpp +++ b/apps/regression/model/logistic_model.cpp @@ -13,24 +13,24 @@ namespace Regression { Layout LogisticModel::layout() { if (m_layout.isUninitialized()) { const Layout exponentLayoutChildren[] = { - CharLayout('-', KDFont::SmallFont), - CharLayout('b', KDFont::SmallFont), - CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont), - CharLayout('X', KDFont::SmallFont) + CharLayout::Builder('-', KDFont::SmallFont), + CharLayout::Builder('b', KDFont::SmallFont), + CharLayout::Builder(Ion::Charset::MiddleDot, KDFont::SmallFont), + CharLayout::Builder('X', KDFont::SmallFont) }; const Layout layoutChildren[] = { - CharLayout('1', KDFont::SmallFont), - CharLayout('+', KDFont::SmallFont), - CharLayout('a', KDFont::SmallFont), - CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont), - CharLayout('e', KDFont::SmallFont), + CharLayout::Builder('1', KDFont::SmallFont), + CharLayout::Builder('+', KDFont::SmallFont), + CharLayout::Builder('a', KDFont::SmallFont), + CharLayout::Builder(Ion::Charset::MiddleDot, KDFont::SmallFont), + CharLayout::Builder('e', KDFont::SmallFont), VerticalOffsetLayout::Builder( HorizontalLayout::Builder(exponentLayoutChildren, 4), VerticalOffsetLayoutNode::Type::Superscript ) }; m_layout = FractionLayout::Builder( - CharLayout('c', KDFont::SmallFont), + CharLayout::Builder('c', KDFont::SmallFont), HorizontalLayout::Builder(layoutChildren, 6) ); } diff --git a/apps/regression/model/power_model.cpp b/apps/regression/model/power_model.cpp index 9825d0afa..4f341c4bf 100644 --- a/apps/regression/model/power_model.cpp +++ b/apps/regression/model/power_model.cpp @@ -13,11 +13,11 @@ namespace Regression { Layout PowerModel::layout() { if (m_layout.isUninitialized()) { const Layout layoutChildren[] = { - CharLayout('a', KDFont::SmallFont), - CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont), - CharLayout('X', KDFont::SmallFont), + CharLayout::Builder('a', KDFont::SmallFont), + CharLayout::Builder(Ion::Charset::MiddleDot, KDFont::SmallFont), + CharLayout::Builder('X', KDFont::SmallFont), VerticalOffsetLayout::Builder( - CharLayout('b', KDFont::SmallFont), + CharLayout::Builder('b', KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Superscript ), }; diff --git a/apps/regression/model/quadratic_model.cpp b/apps/regression/model/quadratic_model.cpp index 698680ba6..0babfe9d6 100644 --- a/apps/regression/model/quadratic_model.cpp +++ b/apps/regression/model/quadratic_model.cpp @@ -20,19 +20,19 @@ namespace Regression { Layout QuadraticModel::layout() { if (m_layout.isUninitialized()) { const Layout layoutChildren[] = { - CharLayout('a', KDFont::SmallFont), - CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont), - CharLayout('X', KDFont::SmallFont), + CharLayout::Builder('a', KDFont::SmallFont), + CharLayout::Builder(Ion::Charset::MiddleDot, KDFont::SmallFont), + CharLayout::Builder('X', KDFont::SmallFont), VerticalOffsetLayout::Builder( - CharLayout('2', KDFont::SmallFont), + CharLayout::Builder('2', KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Superscript ), - CharLayout('+', KDFont::SmallFont), - CharLayout('b', KDFont::SmallFont), - CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont), - CharLayout('X', KDFont::SmallFont), - CharLayout('+', KDFont::SmallFont), - CharLayout('c', KDFont::SmallFont), + CharLayout::Builder('+', KDFont::SmallFont), + CharLayout::Builder('b', KDFont::SmallFont), + CharLayout::Builder(Ion::Charset::MiddleDot, KDFont::SmallFont), + CharLayout::Builder('X', KDFont::SmallFont), + CharLayout::Builder('+', KDFont::SmallFont), + CharLayout::Builder('c', KDFont::SmallFont), }; m_layout = HorizontalLayout::Builder(layoutChildren, 10); } @@ -48,11 +48,11 @@ Expression QuadraticModel::simplifiedExpression(double * modelCoefficients, Poin Multiplication::Builder( Number::DecimalNumber(a), Power::Builder( - Symbol('x'), - Decimal(2.0))), + Symbol::Builder('x'), + Decimal::Builder(2.0))), Multiplication::Builder( Number::DecimalNumber(b), - Symbol('x')), + Symbol::Builder('x')), Number::DecimalNumber(c) }; Expression result = Addition::Builder(addChildren, 3); diff --git a/apps/regression/model/quartic_model.cpp b/apps/regression/model/quartic_model.cpp index 3c7382fa8..c1dbd87ca 100644 --- a/apps/regression/model/quartic_model.cpp +++ b/apps/regression/model/quartic_model.cpp @@ -20,35 +20,35 @@ namespace Regression { Layout QuarticModel::layout() { if (m_layout.isUninitialized()) { const Layout layoutChildren[] = { - CharLayout('a', KDFont::SmallFont), - CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont), - CharLayout('X', KDFont::SmallFont), + CharLayout::Builder('a', KDFont::SmallFont), + CharLayout::Builder(Ion::Charset::MiddleDot, KDFont::SmallFont), + CharLayout::Builder('X', KDFont::SmallFont), VerticalOffsetLayout::Builder( - CharLayout('4', KDFont::SmallFont), + CharLayout::Builder('4', KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Superscript ), - CharLayout('+', KDFont::SmallFont), - CharLayout('b', KDFont::SmallFont), - CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont), - CharLayout('X', KDFont::SmallFont), + CharLayout::Builder('+', KDFont::SmallFont), + CharLayout::Builder('b', KDFont::SmallFont), + CharLayout::Builder(Ion::Charset::MiddleDot, KDFont::SmallFont), + CharLayout::Builder('X', KDFont::SmallFont), VerticalOffsetLayout::Builder( - CharLayout('3', KDFont::SmallFont), + CharLayout::Builder('3', KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Superscript ), - CharLayout('+', KDFont::SmallFont), - CharLayout('c', KDFont::SmallFont), - CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont), - CharLayout('X', KDFont::SmallFont), + CharLayout::Builder('+', KDFont::SmallFont), + CharLayout::Builder('c', KDFont::SmallFont), + CharLayout::Builder(Ion::Charset::MiddleDot, KDFont::SmallFont), + CharLayout::Builder('X', KDFont::SmallFont), VerticalOffsetLayout::Builder( - CharLayout('2', KDFont::SmallFont), + CharLayout::Builder('2', KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Superscript ), - CharLayout('+', KDFont::SmallFont), - CharLayout('d', KDFont::SmallFont), - CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont), - CharLayout('X', KDFont::SmallFont), - CharLayout('+', KDFont::SmallFont), - CharLayout('e', KDFont::SmallFont), + CharLayout::Builder('+', KDFont::SmallFont), + CharLayout::Builder('d', KDFont::SmallFont), + CharLayout::Builder(Ion::Charset::MiddleDot, KDFont::SmallFont), + CharLayout::Builder('X', KDFont::SmallFont), + CharLayout::Builder('+', KDFont::SmallFont), + CharLayout::Builder('e', KDFont::SmallFont), }; m_layout = HorizontalLayout::Builder(layoutChildren, 20); } @@ -66,24 +66,24 @@ Expression QuarticModel::simplifiedExpression(double * modelCoefficients, Poinca Multiplication::Builder( Number::DecimalNumber(a), Power::Builder( - Symbol('x'), - Decimal(4.0))), + Symbol::Builder('x'), + Decimal::Builder(4.0))), // b*x^3 Multiplication::Builder( Number::DecimalNumber(b), Power::Builder( - Symbol('x'), - Decimal(3.0))), + Symbol::Builder('x'), + Decimal::Builder(3.0))), // c*x^2 Multiplication::Builder( Number::DecimalNumber(c), Power::Builder( - Symbol('x'), - Decimal(2.0))), + Symbol::Builder('x'), + Decimal::Builder(2.0))), // d*x Multiplication::Builder( Number::DecimalNumber(d), - Symbol('x')), + Symbol::Builder('x')), // e Number::DecimalNumber(e) }; diff --git a/apps/regression/model/trigonometric_model.cpp b/apps/regression/model/trigonometric_model.cpp index f1151036a..ed919a59e 100644 --- a/apps/regression/model/trigonometric_model.cpp +++ b/apps/regression/model/trigonometric_model.cpp @@ -21,20 +21,20 @@ namespace Regression { Layout TrigonometricModel::layout() { if (m_layout.isUninitialized()) { const Layout layoutChildren[] = { - CharLayout('a', KDFont::SmallFont), - CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont), - CharLayout('s', KDFont::SmallFont), - CharLayout('i', KDFont::SmallFont), - CharLayout('n', KDFont::SmallFont), - CharLayout('(', KDFont::SmallFont), - CharLayout('b', KDFont::SmallFont), - CharLayout(Ion::Charset::MiddleDot, KDFont::SmallFont), - CharLayout('X', KDFont::SmallFont), - CharLayout('+', KDFont::SmallFont), - CharLayout('c', KDFont::SmallFont), - CharLayout(')', KDFont::SmallFont), - CharLayout('+', KDFont::SmallFont), - CharLayout('d', KDFont::SmallFont) + CharLayout::Builder('a', KDFont::SmallFont), + CharLayout::Builder(Ion::Charset::MiddleDot, KDFont::SmallFont), + CharLayout::Builder('s', KDFont::SmallFont), + CharLayout::Builder('i', KDFont::SmallFont), + CharLayout::Builder('n', KDFont::SmallFont), + CharLayout::Builder('(', KDFont::SmallFont), + CharLayout::Builder('b', KDFont::SmallFont), + CharLayout::Builder(Ion::Charset::MiddleDot, KDFont::SmallFont), + CharLayout::Builder('X', KDFont::SmallFont), + CharLayout::Builder('+', KDFont::SmallFont), + CharLayout::Builder('c', KDFont::SmallFont), + CharLayout::Builder(')', KDFont::SmallFont), + CharLayout::Builder('+', KDFont::SmallFont), + CharLayout::Builder('d', KDFont::SmallFont) }; m_layout = HorizontalLayout::Builder(layoutChildren, 14); } @@ -55,7 +55,7 @@ Expression TrigonometricModel::simplifiedExpression(double * modelCoefficients, Addition::Builder( Multiplication::Builder( Number::DecimalNumber(b), - Symbol('x')), + Symbol::Builder('x')), Number::DecimalNumber(c)))), Number::DecimalNumber(d)); PoincareHelpers::Simplify(&result, *context); diff --git a/apps/regression/regression_context.cpp b/apps/regression/regression_context.cpp index b7d480743..1550cd2bc 100644 --- a/apps/regression/regression_context.cpp +++ b/apps/regression/regression_context.cpp @@ -22,7 +22,7 @@ const Expression RegressionContext::expressionForSymbol(const SymbolAbstract & s assert(m_seriesPairIndex >= 0); assert(m_seriesPairIndex < m_store->numberOfPairsOfSeries(series)); - return Float(m_store->get(series, storeI, m_seriesPairIndex)); + return Float::Builder(m_store->get(series, storeI, m_seriesPairIndex)); } else { return m_parentContext->expressionForSymbol(symbol, clone); } diff --git a/apps/sequence/cache_context.cpp b/apps/sequence/cache_context.cpp index b16a3d4f3..96fb44608 100644 --- a/apps/sequence/cache_context.cpp +++ b/apps/sequence/cache_context.cpp @@ -22,7 +22,7 @@ const Expression CacheContext::expressionForSymbol(const SymbolAbstract & sym && (strcmp(symbol.name()+1, "(n)") == 0 || strcmp(symbol.name()+1, "(n+1)") == 0)) { Symbol s = const_cast(static_cast(symbol)); - return Float(m_values[nameIndexForSymbol(s)][rankIndexForSymbol(s)]); + return Float::Builder(m_values[nameIndexForSymbol(s)][rankIndexForSymbol(s)]); } return VariableContext::expressionForSymbol(symbol, clone); } diff --git a/apps/sequence/graph/term_sum_controller.cpp b/apps/sequence/graph/term_sum_controller.cpp index 033a0ce65..35fcfb49f 100644 --- a/apps/sequence/graph/term_sum_controller.cpp +++ b/apps/sequence/graph/term_sum_controller.cpp @@ -51,9 +51,9 @@ double TermSumController::cursorNextStep(double x, int direction) { Layout TermSumController::createFunctionLayout(const char * functionName) { return HorizontalLayout::Builder( - CharLayout(functionName[0], KDFont::SmallFont), + CharLayout::Builder(functionName[0], KDFont::SmallFont), VerticalOffsetLayout::Builder( - CharLayout('n', KDFont::SmallFont), + CharLayout::Builder('n', KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Subscript ) ); diff --git a/apps/sequence/list/sequence_toolbox.cpp b/apps/sequence/list/sequence_toolbox.cpp index ab0468c5c..5dbcd3380 100644 --- a/apps/sequence/list/sequence_toolbox.cpp +++ b/apps/sequence/list/sequence_toolbox.cpp @@ -77,18 +77,18 @@ void SequenceToolbox::buildExtraCellsLayouts(const char * sequenceName, int recu for (int j = 0; j < recurrenceDepth; j++) { const char * indice = j == 0 ? "n" : "n+1"; m_addedCellLayout[j] = HorizontalLayout::Builder( - CharLayout(sequenceName[0], KDFont::LargeFont), + CharLayout::Builder(sequenceName[0], KDFont::LargeFont), VerticalOffsetLayout::Builder(LayoutHelper::String(indice, strlen(indice), KDFont::LargeFont), VerticalOffsetLayoutNode::Type::Subscript) ); m_addedCellLayout[j+recurrenceDepth] = HorizontalLayout::Builder( - CharLayout(otherSequenceName[0], KDFont::LargeFont), + CharLayout::Builder(otherSequenceName[0], KDFont::LargeFont), VerticalOffsetLayout::Builder(LayoutHelper::String(indice, strlen(indice), KDFont::LargeFont), VerticalOffsetLayoutNode::Type::Subscript) ); } if (recurrenceDepth < 2) { const char * indice = recurrenceDepth == 0 ? "n" : (recurrenceDepth == 1 ? "n+1" : "n+2"); m_addedCellLayout[2*recurrenceDepth] = HorizontalLayout::Builder( - CharLayout(otherSequenceName[0], KDFont::LargeFont), + CharLayout::Builder(otherSequenceName[0], KDFont::LargeFont), VerticalOffsetLayout::Builder(LayoutHelper::String(indice, strlen(indice), KDFont::LargeFont), VerticalOffsetLayoutNode::Type::Subscript) ); } diff --git a/apps/sequence/list/type_parameter_controller.cpp b/apps/sequence/list/type_parameter_controller.cpp index 80ae5ec85..71bace67e 100644 --- a/apps/sequence/list/type_parameter_controller.cpp +++ b/apps/sequence/list/type_parameter_controller.cpp @@ -116,7 +116,7 @@ void TypeParameterController::willDisplayCellAtLocation(HighlightCell * cell, in } const char * subscripts[3] = {"n", "n+1", "n+2"}; m_layouts[j] = HorizontalLayout::Builder( - CharLayout(nextName[0], font), + CharLayout::Builder(nextName[0], font), VerticalOffsetLayout::Builder(LayoutHelper::String(subscripts[j], strlen(subscripts[j]), font), VerticalOffsetLayoutNode::Type::Subscript) ); ExpressionTableCellWithPointer * myCell = (ExpressionTableCellWithPointer *)cell; diff --git a/apps/sequence/sequence.cpp b/apps/sequence/sequence.cpp index ff7555ee2..d413343b0 100644 --- a/apps/sequence/sequence.cpp +++ b/apps/sequence/sequence.cpp @@ -147,8 +147,8 @@ int Sequence::numberOfElements() { Poincare::Layout Sequence::nameLayout() { if (m_nameLayout.isUninitialized()) { m_nameLayout = HorizontalLayout::Builder( - CharLayout(name()[0], KDFont::SmallFont), - VerticalOffsetLayout::Builder(CharLayout('n', KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Subscript) + CharLayout::Builder(name()[0], KDFont::SmallFont), + VerticalOffsetLayout::Builder(CharLayout::Builder('n', KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Subscript) ); } return m_nameLayout; @@ -158,16 +158,16 @@ Poincare::Layout Sequence::definitionName() { if (m_definitionName.isUninitialized()) { if (m_type == Type::Explicit) { m_definitionName = HorizontalLayout::Builder( - CharLayout(name()[0], k_layoutFont), + CharLayout::Builder(name()[0], k_layoutFont), VerticalOffsetLayout::Builder(LayoutHelper::String("n", 1, k_layoutFont), VerticalOffsetLayoutNode::Type::Subscript)); } else if (m_type == Type::SingleRecurrence) { m_definitionName = HorizontalLayout::Builder( - CharLayout(name()[0], k_layoutFont), + CharLayout::Builder(name()[0], k_layoutFont), VerticalOffsetLayout::Builder(LayoutHelper::String("n+1", 3, k_layoutFont), VerticalOffsetLayoutNode::Type::Subscript)); } else { assert(m_type == Type::DoubleRecurrence); m_definitionName = HorizontalLayout::Builder( - CharLayout(name()[0], k_layoutFont), + CharLayout::Builder(name()[0], k_layoutFont), VerticalOffsetLayout::Builder(LayoutHelper::String("n+2", 3, k_layoutFont), VerticalOffsetLayoutNode::Type::Subscript)); } } @@ -183,7 +183,7 @@ Poincare::Layout Sequence::firstInitialConditionName() { { Layout indexLayout = LayoutHelper::String(buffer, strlen(buffer), k_layoutFont); m_firstInitialConditionName = HorizontalLayout::Builder( - CharLayout(name()[0], k_layoutFont), + CharLayout::Builder(name()[0], k_layoutFont), VerticalOffsetLayout::Builder(indexLayout, VerticalOffsetLayoutNode::Type::Subscript)); } return m_firstInitialConditionName; @@ -196,7 +196,7 @@ Poincare::Layout Sequence::secondInitialConditionName() { if (m_type == Type::DoubleRecurrence) { Layout indexLayout = LayoutHelper::String(buffer, strlen(buffer), k_layoutFont); m_secondInitialConditionName = HorizontalLayout::Builder( - CharLayout(name()[0], k_layoutFont), + CharLayout::Builder(name()[0], k_layoutFont), VerticalOffsetLayout::Builder(indexLayout, VerticalOffsetLayoutNode::Type::Subscript)); } } @@ -247,10 +247,10 @@ T Sequence::approximateToNextRank(int n, SequenceContext * sqctx) const { T vn = sqctx->valueOfSequenceAtPreviousRank(1, 0); T vnm1 = sqctx->valueOfSequenceAtPreviousRank(1, 1); T vnm2 = sqctx->valueOfSequenceAtPreviousRank(1, 2); - Poincare::Symbol vnSymbol("v(n)", 4); - Poincare::Symbol vn1Symbol("v(n+1)", 6); - Poincare::Symbol unSymbol("u(n)", 4); - Poincare::Symbol un1Symbol("u(n+1)", 6); + Poincare::Symbol vnSymbol = Symbol::Builder("v(n)", 4); + Poincare::Symbol vn1Symbol = Symbol::Builder("v(n+1)", 6); + Poincare::Symbol unSymbol = Symbol::Builder("u(n)", 4); + Poincare::Symbol un1Symbol = Symbol::Builder("u(n+1)", 6); switch (m_type) { case Type::Explicit: { diff --git a/apps/settings/sub_menu/preferences_controller.cpp b/apps/settings/sub_menu/preferences_controller.cpp index ccc052317..bb96f02cf 100644 --- a/apps/settings/sub_menu/preferences_controller.cpp +++ b/apps/settings/sub_menu/preferences_controller.cpp @@ -84,7 +84,7 @@ Layout layoutForPreferences(I18n::Message message) { // Complex format case I18n::Message::Real: { - return CharLayout('x', KDFont::SmallFont); + return CharLayout::Builder('x', KDFont::SmallFont); } case I18n::Message::Cartesian: { diff --git a/apps/shared/global_context.cpp b/apps/shared/global_context.cpp index 83e4da400..336945f11 100644 --- a/apps/shared/global_context.cpp +++ b/apps/shared/global_context.cpp @@ -71,7 +71,7 @@ void GlobalContext::setExpressionForSymbol(const Expression & expression, const Ion::Storage::Record record = SymbolAbstractRecordWithBaseName(symbol.name()); Expression e = ExpressionFromRecord(record); if (e.isUninitialized()) { - e = Undefined(); + e = Undefined::Builder(); } Expression finalExpression = expression.clone().replaceSymbolWithExpression(symbol, e); diff --git a/apps/shared/storage_cartesian_function.cpp b/apps/shared/storage_cartesian_function.cpp index ff46ec7cb..d07eb935d 100644 --- a/apps/shared/storage_cartesian_function.cpp +++ b/apps/shared/storage_cartesian_function.cpp @@ -85,7 +85,7 @@ void StorageCartesianFunction::setDisplayDerivative(bool display) { } double StorageCartesianFunction::approximateDerivative(double x, Poincare::Context * context) const { - Poincare::Derivative derivative = Poincare::Derivative::Builder(expressionReduced(context).clone(), Symbol(Symbol::SpecialSymbols::UnknownX), Poincare::Float(x)); // derivative takes ownership of Poincare::Float(x) and the clone of expression + Poincare::Derivative derivative = Poincare::Derivative::Builder(expressionReduced(context).clone(), Symbol::Builder(Symbol::SpecialSymbols::UnknownX), Poincare::Float::Builder(x)); // derivative takes ownership of Poincare::Float::Builder(x) and the clone of expression /* TODO: when we approximate derivative, we might want to simplify the * derivative here. However, we might want to do it once for all x (to avoid * lagging in the derivative table. */ @@ -94,7 +94,7 @@ double StorageCartesianFunction::approximateDerivative(double x, Poincare::Conte double StorageCartesianFunction::sumBetweenBounds(double start, double end, Poincare::Context * context) const { // TODO: this does not work yet because integral does not understand UnknownX - Poincare::Integral integral = Poincare::Integral::Builder(expressionReduced(context).clone(), Symbol(Symbol::SpecialSymbols::UnknownX), Poincare::Float(start), Poincare::Float(end)); // Integral takes ownership of args + Poincare::Integral integral = Poincare::Integral::Builder(expressionReduced(context).clone(), Symbol::Builder(Symbol::SpecialSymbols::UnknownX), Poincare::Float::Builder(start), Poincare::Float::Builder(end)); // Integral takes ownership of args /* TODO: when we approximate integral, we might want to simplify the integral * here. However, we might want to do it once for all x (to avoid lagging in * the derivative table. */ diff --git a/apps/shared/storage_expression_model.cpp b/apps/shared/storage_expression_model.cpp index 1a6aabf17..bfb274c7b 100644 --- a/apps/shared/storage_expression_model.cpp +++ b/apps/shared/storage_expression_model.cpp @@ -87,7 +87,7 @@ Ion::Storage::Record::ErrorStatus StorageExpressionModel::setContent(const char // Compute the expression to store, without replacing symbols expressionToStore = Expression::Parse(c); if (!expressionToStore.isUninitialized()) { - expressionToStore = expressionToStore.replaceUnknown(Symbol('x')); //TODO Beware of non x unknowns! (for instance whe sequences are in the storage) + expressionToStore = expressionToStore.replaceUnknown(Symbol::Builder('x')); //TODO Beware of non x unknowns! (for instance whe sequences are in the storage) } } return setExpressionContent(expressionToStore); diff --git a/apps/shared/storage_sum_graph_controller.cpp b/apps/shared/storage_sum_graph_controller.cpp index 0e950cebb..bc164fb5a 100644 --- a/apps/shared/storage_sum_graph_controller.cpp +++ b/apps/shared/storage_sum_graph_controller.cpp @@ -243,7 +243,7 @@ void StorageSumGraphController::LegendView::setSumSymbol(Step step, double start m_sumLayout = CondensedSumLayout::Builder( LayoutHelper::String(sigma, sizeof(sigma)), LayoutHelper::String(buffer, strlen(buffer), k_font), - EmptyLayout(EmptyLayoutNode::Color::Yellow, false, k_font, false)); + EmptyLayout::Builder(EmptyLayoutNode::Color::Yellow, false, k_font, false)); } else { m_sumLayout = LayoutHelper::String(sigma, sizeof(sigma)); char buffer[2+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)]; diff --git a/apps/shared/sum_graph_controller.cpp b/apps/shared/sum_graph_controller.cpp index 384279450..ee03dbc2b 100644 --- a/apps/shared/sum_graph_controller.cpp +++ b/apps/shared/sum_graph_controller.cpp @@ -242,7 +242,7 @@ void SumGraphController::LegendView::setSumSymbol(Step step, double start, doubl m_sumLayout = CondensedSumLayout::Builder( LayoutHelper::String(sigma, sizeof(sigma)), LayoutHelper::String(buffer, strlen(buffer), KDFont::SmallFont), - EmptyLayout(EmptyLayoutNode::Color::Yellow, false, KDFont::SmallFont, false)); + EmptyLayout::Builder(EmptyLayoutNode::Color::Yellow, false, KDFont::SmallFont, false)); } else { m_sumLayout = LayoutHelper::String(sigma, sizeof(sigma)); constexpr size_t bufferSize = 2+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits); diff --git a/apps/solver/equation.cpp b/apps/solver/equation.cpp index faabddbf3..15c9e1578 100644 --- a/apps/solver/equation.cpp +++ b/apps/solver/equation.cpp @@ -30,11 +30,11 @@ Expression Equation::standardForm(Context * context) const { if (m_standardForm.isUninitialized()) { const Expression e = expression(context); if (e.type() == ExpressionNode::Type::Unreal) { - m_standardForm = Unreal(); + m_standardForm = Unreal::Builder(); return m_standardForm; } if (e.recursivelyMatches([](const Expression e, Context & context, bool replaceSymbols) { return e.type() == ExpressionNode::Type::Undefined || e.type() == ExpressionNode::Type::Infinity || Expression::IsMatrix(e, context, replaceSymbols); }, *context, true)) { - m_standardForm = Undefined(); + m_standardForm = Undefined::Builder(); return m_standardForm; } if (e.type() == ExpressionNode::Type::Equal) { @@ -43,7 +43,7 @@ Expression Equation::standardForm(Context * context) const { } else { assert(e.type() == ExpressionNode::Type::Rational && static_cast(e).isOne()); // The equality was reduced which means the equality was always true. - m_standardForm = Rational(0); + m_standardForm = Rational::Builder(0); } } return m_standardForm; diff --git a/apps/solver/equation_store.cpp b/apps/solver/equation_store.cpp index 8f9e841af..b81de3552 100644 --- a/apps/solver/equation_store.cpp +++ b/apps/solver/equation_store.cpp @@ -257,20 +257,20 @@ EquationStore::Error EquationStore::oneDimensialPolynomialSolve(Expression exact /* Equation ax^2+bx+c = 0 */ assert(degree == 2); // Compute delta = b*b-4ac - Expression delta = Subtraction::Builder(Power::Builder(coefficients[1].clone(), Rational(2)), Multiplication::Builder(Rational(4), coefficients[0].clone(), coefficients[2].clone())); + Expression delta = Subtraction::Builder(Power::Builder(coefficients[1].clone(), Rational::Builder(2)), Multiplication::Builder(Rational::Builder(4), coefficients[0].clone(), coefficients[2].clone())); delta = delta.simplify(*context, updatedComplexFormat(), Poincare::Preferences::sharedPreferences()->angleUnit()); if (delta.isUninitialized()) { - delta = Poincare::Undefined(); + delta = Poincare::Undefined::Builder(); } if (delta.isRationalZero()) { // if delta = 0, x0=x1= -b/(2a) - exactSolutions[0] = Division::Builder(Opposite::Builder(coefficients[1]), Multiplication::Builder(Rational(2), coefficients[2])); + exactSolutions[0] = Division::Builder(Opposite::Builder(coefficients[1]), Multiplication::Builder(Rational::Builder(2), coefficients[2])); m_numberOfSolutions = 2; } else { // x0 = (-b-sqrt(delta))/(2a) - exactSolutions[0] = Division::Builder(Subtraction::Builder(Opposite::Builder(coefficients[1].clone()), SquareRoot::Builder(delta.clone())), Multiplication::Builder(Rational(2), coefficients[2].clone())); + exactSolutions[0] = Division::Builder(Subtraction::Builder(Opposite::Builder(coefficients[1].clone()), SquareRoot::Builder(delta.clone())), Multiplication::Builder(Rational::Builder(2), coefficients[2].clone())); // x1 = (-b+sqrt(delta))/(2a) - exactSolutions[1] = Division::Builder(Addition::Builder(Opposite::Builder(coefficients[1]), SquareRoot::Builder(delta.clone())), Multiplication::Builder(Rational(2), coefficients[2])); + exactSolutions[1] = Division::Builder(Addition::Builder(Opposite::Builder(coefficients[1]), SquareRoot::Builder(delta.clone())), Multiplication::Builder(Rational::Builder(2), coefficients[2])); m_numberOfSolutions = 3; } exactSolutions[m_numberOfSolutions-1] = delta; @@ -285,47 +285,47 @@ EquationStore::Error EquationStore::oneDimensialPolynomialSolve(Expression exact Expression * c = coefficients[1]; Expression * d = coefficients[0]; // Delta = b^2*c^2+18abcd-27a^2*d^2-4ac^3-4db^3 - Expression * mult0Operands[2] = {new Power::Builder(b->clone(), new Rational(2), false), new Power::Builder(c->clone(), new Rational(2), false)}; - Expression * mult1Operands[5] = {new Rational(18), a->clone(), b->clone(), c->clone(), d->clone()}; - Expression * mult2Operands[3] = {new Rational(-27), new Power::Builder(a->clone(), new Rational(2), false), new Power::Builder(d->clone(), new Rational(2), false)}; - Expression * mult3Operands[3] = {new Rational(-4), a->clone(), new Power::Builder(c->clone(), new Rational(3), false)}; - Expression * mult4Operands[3] = {new Rational(-4), d->clone(), new Power::Builder(b->clone(), new Rational(3), false)}; + Expression * mult0Operands[2] = {new Power::Builder(b->clone(), new Rational::Builder(2), false), new Power::Builder(c->clone(), new Rational::Builder(2), false)}; + Expression * mult1Operands[5] = {new Rational::Builder(18), a->clone(), b->clone(), c->clone(), d->clone()}; + Expression * mult2Operands[3] = {new Rational::Builder(-27), new Power::Builder(a->clone(), new Rational::Builder(2), false), new Power::Builder(d->clone(), new Rational::Builder(2), false)}; + Expression * mult3Operands[3] = {new Rational::Builder(-4), a->clone(), new Power::Builder(c->clone(), new Rational::Builder(3), false)}; + Expression * mult4Operands[3] = {new Rational::Builder(-4), d->clone(), new Power::Builder(b->clone(), new Rational::Builder(3), false)}; Expression * add0Operands[5] = {new Multiplication::Builder(mult0Operands, 2, false), new Multiplication::Builder(mult1Operands, 5, false), new Multiplication::Builder(mult2Operands, 3, false), new Multiplication::Builder(mult3Operands, 3, false), new Multiplication::Builder(mult4Operands, 3, false)}; Expression * delta = new Addition(add0Operands, 5, false); PoincareHelpers::Simplify(&delta, *context); // Delta0 = b^2-3ac - Expression * mult5Operands[3] = {new Rational(3), a->clone(), c->clone()}; - Expression * delta0 = new Subtraction::Builder(new Power::Builder(b->clone(), new Rational(2), false), new Multiplication::Builder(mult5Operands, 3, false), false); + Expression * mult5Operands[3] = {new Rational::Builder(3), a->clone(), c->clone()}; + Expression * delta0 = new Subtraction::Builder(new Power::Builder(b->clone(), new Rational::Builder(2), false), new Multiplication::Builder(mult5Operands, 3, false), false); Reduce(&delta0, *context); if (delta->isRationalZero()) { if (delta0->isRationalZero()) { // delta0 = 0 && delta = 0 --> x0 = -b/(3a) delete delta0; - m_exactSolutions[0] = new Opposite::Builder(new Division::Builder(b, new Multiplication::Builder(new Rational(3), a, false), false), false); + m_exactSolutions[0] = new Opposite::Builder(new Division::Builder(b, new Multiplication::Builder(new Rational::Builder(3), a, false), false), false); m_numberOfSolutions = 1; delete c; delete d; } else { // delta = 0 --> x0 = (9ad-bc)/(2delta0) // --> x1 = (4abc-9a^2d-b^3)/(a*delta0) - Expression * mult6Operands[3] = {new Rational(9), a, d}; - m_exactSolutions[0] = new Division::Builder(new Subtraction::Builder(new Multiplication::Builder(mult6Operands, 3, false), new Multiplication::Builder(b, c, false), false), new Multiplication::Builder(new Rational(2), delta0, false), false); - Expression * mult7Operands[4] = {new Rational(4), a->clone(), b->clone(), c->clone()}; - Expression * mult8Operands[3] = {new Rational(-9), new Power::Builder(a->clone(), new Rational(2), false), d->clone()}; - Expression * add1Operands[3] = {new Multiplication::Builder(mult7Operands, 4, false), new Multiplication::Builder(mult8Operands,3, false), new Opposite::Builder(new Power::Builder(b->clone(), new Rational(3), false), false)}; + Expression * mult6Operands[3] = {new Rational::Builder(9), a, d}; + m_exactSolutions[0] = new Division::Builder(new Subtraction::Builder(new Multiplication::Builder(mult6Operands, 3, false), new Multiplication::Builder(b, c, false), false), new Multiplication::Builder(new Rational::Builder(2), delta0, false), false); + Expression * mult7Operands[4] = {new Rational::Builder(4), a->clone(), b->clone(), c->clone()}; + Expression * mult8Operands[3] = {new Rational::Builder(-9), new Power::Builder(a->clone(), new Rational::Builder(2), false), d->clone()}; + Expression * add1Operands[3] = {new Multiplication::Builder(mult7Operands, 4, false), new Multiplication::Builder(mult8Operands,3, false), new Opposite::Builder(new Power::Builder(b->clone(), new Rational::Builder(3), false), false)}; m_exactSolutions[1] = new Division::Builder(new Addition(add1Operands, 3, false), new Multiplication::Builder(a->clone(), delta0, false), false); m_numberOfSolutions = 2; } } else { // delta1 = 2b^3-9abc+27a^2*d - Expression * mult9Operands[4] = {new Rational(-9), a, b, c}; - Expression * mult10Operands[3] = {new Rational(27), new Power::Builder(a->clone(), new Rational(2), false), d}; - Expression * add2Operands[3] = {new Multiplication::Builder(new Rational(2), new Power::Builder(b->clone(), new Rational(3), false), false), new Multiplication::Builder(mult9Operands, 4, false), new Multiplication::Builder(mult10Operands, 3, false)}; + Expression * mult9Operands[4] = {new Rational::Builder(-9), a, b, c}; + Expression * mult10Operands[3] = {new Rational::Builder(27), new Power::Builder(a->clone(), new Rational::Builder(2), false), d}; + Expression * add2Operands[3] = {new Multiplication::Builder(new Rational::Builder(2), new Power::Builder(b->clone(), new Rational::Builder(3), false), false), new Multiplication::Builder(mult9Operands, 4, false), new Multiplication::Builder(mult10Operands, 3, false)}; Expression * delta1 = new Addition(add2Operands, 3, false); // C = Root((delta1+sqrt(-27a^2*delta))/2, 3) - Expression * mult11Operands[3] = {new Rational(-27), new Power::Builder(a->clone(), new Rational(2), false), (*delta)->clone()}; - Expression * c = new Power::Builder(new Division::Builder(new Addition(delta1, new SquareRoot(new Multiplication::Builder(mult11Operands, 3, false), false), false), new Rational(2), false), new Rational(1,3), false); - Expression * unary3roots[2] = {new Addition(new Rational(-1,2), new Division::Builder(new Multiplication::Builder(new SquareRoot(new Rational(3), false), new Constant(Ion::Charset::IComplex), false), new Rational(2), false), false), new Subtraction::Builder(new Rational(-1,2), new Division::Builder(new Multiplication::Builder(new SquareRoot(new Rational(3), false), new Constant(Ion::Charset::IComplex), false), new Rational(2), false), false)}; + Expression * mult11Operands[3] = {new Rational::Builder(-27), new Power::Builder(a->clone(), new Rational::Builder(2), false), (*delta)->clone()}; + Expression * c = new Power::Builder(new Division::Builder(new Addition(delta1, new SquareRoot(new Multiplication::Builder(mult11Operands, 3, false), false), false), new Rational::Builder(2), false), new Rational::Builder(1,3), false); + Expression * unary3roots[2] = {new Addition(new Rational::Builder(-1,2), new Division::Builder(new Multiplication::Builder(new SquareRoot(new Rational::Builder(3), false), new Constant::Builder(Ion::Charset::IComplex), false), new Rational::Builder(2), false), false), new Subtraction::Builder(new Rational::Builder(-1,2), new Division::Builder(new Multiplication::Builder(new SquareRoot(new Rational::Builder(3), false), new Constant::Builder(Ion::Charset::IComplex), false), new Rational::Builder(2), false), false)}; // x_k = -1/(3a)*(b+C*z+delta0/(zC)) with z = unary cube root for (int k = 0; k < 3; k++) { Expression * ccopy = c; @@ -335,7 +335,7 @@ EquationStore::Error EquationStore::oneDimensialPolynomialSolve(Expression exact delta0copy = delta0->clone(); } Expression * add3Operands[3] = {b->clone(), ccopy, new Division::Builder(delta0copy, ccopy->clone(), false)}; - m_exactSolutions[k] = new Multiplication::Builder(new Division::Builder(new Rational(-1), new Multiplication::Builder(new Rational(3), a->clone(), false), false), new Addition(add3Operands, 3, false), false); + m_exactSolutions[k] = new Multiplication::Builder(new Division::Builder(new Rational::Builder(-1), new Multiplication::Builder(new Rational::Builder(3), a->clone(), false), false), new Addition(add3Operands, 3, false), false); } m_numberOfSolutions = 3; } diff --git a/apps/solver/solutions_controller.cpp b/apps/solver/solutions_controller.cpp index 5783f4287..f9b97405b 100644 --- a/apps/solver/solutions_controller.cpp +++ b/apps/solver/solutions_controller.cpp @@ -75,7 +75,7 @@ SolutionsController::SolutionsController(Responder * parentResponder, EquationSt m_delta2Layout(), m_contentView(this) { - m_delta2Layout = HorizontalLayout::Builder(VerticalOffsetLayout::Builder(CharLayout('2', KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Superscript), LayoutHelper::String("-4ac", 4, KDFont::SmallFont)); + m_delta2Layout = HorizontalLayout::Builder(VerticalOffsetLayout::Builder(CharLayout::Builder('2', KDFont::SmallFont), VerticalOffsetLayoutNode::Type::Superscript), LayoutHelper::String("-4ac", 4, KDFont::SmallFont)); char deltaB[] = {Ion::Charset::CapitalDelta, '=', 'b'}; static_cast(m_delta2Layout).addOrMergeChildAtIndex(LayoutHelper::String(deltaB, 3, KDFont::SmallFont), 0, false); for (int i = 0; i < EquationStore::k_maxNumberOfExactSolutions; i++) { diff --git a/apps/statistics/statistics_context.cpp b/apps/statistics/statistics_context.cpp index 1f5260ee9..23830d431 100644 --- a/apps/statistics/statistics_context.cpp +++ b/apps/statistics/statistics_context.cpp @@ -22,7 +22,7 @@ const Expression StatisticsContext::expressionForSymbol(const SymbolAbstract & s assert(m_seriesPairIndex >= 0); assert(m_seriesPairIndex < m_store->numberOfPairsOfSeries(series)); - return Float(m_store->get(series, storeI, m_seriesPairIndex)); + return Float::Builder(m_store->get(series, storeI, m_seriesPairIndex)); } else { return m_parentContext->expressionForSymbol(symbol, clone); } diff --git a/poincare/Makefile b/poincare/Makefile index 891a50338..7fbd144c1 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -3,6 +3,7 @@ SFLAGS += -Ipoincare/include #include poincare/src/simplify/Makefile #include poincare/src/simplification/Makefile objs += $(addprefix poincare/src/,\ + absolute_value_layout.o\ binomial_coefficient_layout.o\ bracket_layout.o\ bracket_pair_layout.o\ @@ -11,6 +12,7 @@ objs += $(addprefix poincare/src/,\ condensed_sum_layout.o\ conjugate_layout.o\ empty_layout.o\ + floor_layout.o\ fraction_layout.o\ grid_layout.o\ horizontal_layout.o\ diff --git a/poincare/include/poincare/absolute_value.h b/poincare/include/poincare/absolute_value.h index 5a2b9ed98..d0eec68d2 100644 --- a/poincare/include/poincare/absolute_value.h +++ b/poincare/include/poincare/absolute_value.h @@ -28,7 +28,7 @@ public: // Approximation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { - return Complex(std::abs(c)); + return Complex::Builder(std::abs(c)); } Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit, computeOnComplex); @@ -49,15 +49,12 @@ class AbsoluteValue final : public Expression { friend class AbsoluteValueNode; public: AbsoluteValue(const AbsoluteValueNode * n) : Expression(n) {} - static AbsoluteValue Builder(Expression child) { return AbsoluteValue(child); } + static AbsoluteValue Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("abs", 1, &UntypedBuilder); Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); private: - explicit AbsoluteValue(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } Expression setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); }; diff --git a/poincare/include/poincare/absolute_value_layout.h b/poincare/include/poincare/absolute_value_layout.h index a0dfde873..42510c6b0 100644 --- a/poincare/include/poincare/absolute_value_layout.h +++ b/poincare/include/poincare/absolute_value_layout.h @@ -33,13 +33,8 @@ private: class AbsoluteValueLayout final : public Layout { public: - static AbsoluteValueLayout Builder(Layout l) { return AbsoluteValueLayout(l); } -private: - explicit AbsoluteValueLayout(Layout l) : - Layout(TreePool::sharedPool()->createTreeNode()) - { - replaceChildAtIndexInPlace(0, l); - } + static AbsoluteValueLayout Builder(Layout l); + AbsoluteValueLayout() = delete; }; } diff --git a/poincare/include/poincare/addition.h b/poincare/include/poincare/addition.h index 6c4348130..07d482e46 100644 --- a/poincare/include/poincare/addition.h +++ b/poincare/include/poincare/addition.h @@ -29,7 +29,7 @@ public: int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const override; // Evaluation - template static Complex compute(const std::complex c, const std::complex d, Preferences::ComplexFormat complexFormat) { return Complex(c+d); } + template static Complex compute(const std::complex c, const std::complex d, Preferences::ComplexFormat complexFormat) { return Complex::Builder(c+d); } template static MatrixComplex computeOnMatrices(const MatrixComplex m, const MatrixComplex n, Preferences::ComplexFormat complexFormat) { return ApproximationHelper::ElementWiseOnComplexMatrices(m, n, complexFormat, compute); } @@ -61,23 +61,15 @@ private: class Addition final : public NAryExpression { public: Addition(const AdditionNode * n) : NAryExpression(n) {} - static Addition Builder() { return Addition(); } + static Addition Builder(); static Addition Builder(Expression e1) { return Addition::Builder(&e1, 1); } static Addition Builder(Expression e1, Expression e2) { return Addition::Builder(ArrayBuilder(e1, e2).array(), 2); } - static Addition Builder(Expression * children, size_t numberOfChildren) { - Addition a = Addition::Builder(); - for (size_t i = 0; i < numberOfChildren; i++) { - a.addChildAtIndexInPlace(children[i], i, i); - } - return a; - } + static Addition Builder(Expression * children, size_t numberOfChildren); // Expression Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); Expression shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const; private: - Addition() : NAryExpression(TreePool::sharedPool()->createTreeNode()) {} - static const Number NumeralFactor(const Expression & e); static inline int NumberOfNonNumeralFactors(const Expression & e); static inline const Expression FirstNonNumeralFactor(const Expression & e); diff --git a/poincare/include/poincare/arc_cosine.h b/poincare/include/poincare/arc_cosine.h index 421bf8a9f..e15d9a685 100644 --- a/poincare/include/poincare/arc_cosine.h +++ b/poincare/include/poincare/arc_cosine.h @@ -41,15 +41,11 @@ private: class ArcCosine final : public Expression { public: ArcCosine(const ArcCosineNode * n) : Expression(n) {} - static ArcCosine Builder(Expression child) { return ArcCosine(child); } + static ArcCosine Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("acos", 1, &UntypedBuilder); Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); -private: - explicit ArcCosine(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; diff --git a/poincare/include/poincare/arc_sine.h b/poincare/include/poincare/arc_sine.h index dd5f030cd..230e39475 100644 --- a/poincare/include/poincare/arc_sine.h +++ b/poincare/include/poincare/arc_sine.h @@ -40,15 +40,11 @@ private: class ArcSine final : public Expression { public: ArcSine(const ArcSineNode * n) : Expression(n) {} - static ArcSine Builder(Expression child) { return ArcSine(child); } + static ArcSine Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("asin", 1, &UntypedBuilder); Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); -private: - explicit ArcSine(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/arc_tangent.h b/poincare/include/poincare/arc_tangent.h index 8569eed36..5262fc692 100644 --- a/poincare/include/poincare/arc_tangent.h +++ b/poincare/include/poincare/arc_tangent.h @@ -44,15 +44,11 @@ private: class ArcTangent final : public Expression { public: ArcTangent(const ArcTangentNode * n) : Expression(n) {} - static ArcTangent Builder(Expression child) { return ArcTangent(child); } + static ArcTangent Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("atan", 1, &UntypedBuilder); Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); -private: - explicit ArcTangent(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/binomial_coefficient.h b/poincare/include/poincare/binomial_coefficient.h index 1edf2b6ba..f6102a879 100644 --- a/poincare/include/poincare/binomial_coefficient.h +++ b/poincare/include/poincare/binomial_coefficient.h @@ -39,17 +39,13 @@ private: class BinomialCoefficient final : public Expression { public: BinomialCoefficient(const BinomialCoefficientNode * n) : Expression(n) {} - static BinomialCoefficient Builder(Expression child0, Expression child1) { return BinomialCoefficient(child0, child1); } + static BinomialCoefficient Builder(Expression child0, Expression child1); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("binomial", 2, &UntypedBuilder); // Expression Expression shallowReduce(); private: - BinomialCoefficient(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child0); - replaceChildAtIndexInPlace(1, child1); - } constexpr static int k_maxNValue = 300; }; diff --git a/poincare/include/poincare/binomial_coefficient_layout.h b/poincare/include/poincare/binomial_coefficient_layout.h index 756f8862e..b094b5b53 100644 --- a/poincare/include/poincare/binomial_coefficient_layout.h +++ b/poincare/include/poincare/binomial_coefficient_layout.h @@ -43,15 +43,8 @@ private: class BinomialCoefficientLayout final : public Layout { public: - static BinomialCoefficientLayout Builder(Layout n, Layout k) { return BinomialCoefficientLayout(n, k); } - -private: - BinomialCoefficientLayout(Layout n, Layout k) : - Layout(TreePool::sharedPool()->createTreeNode()) - { - replaceChildAtIndexInPlace(0, n); - replaceChildAtIndexInPlace(1, k); - } + static BinomialCoefficientLayout Builder(Layout n, Layout k); + BinomialCoefficientLayout() = delete; }; } diff --git a/poincare/include/poincare/ceiling.h b/poincare/include/poincare/ceiling.h index a7880853b..0a202947c 100644 --- a/poincare/include/poincare/ceiling.h +++ b/poincare/include/poincare/ceiling.h @@ -42,15 +42,11 @@ private: class Ceiling final : public Expression { public: Ceiling(const CeilingNode * n) : Expression(n) {} - static Ceiling Builder(Expression child) { return Ceiling(child); } + static Ceiling Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("ceil", 1, &UntypedBuilder); Expression shallowReduce(); -private: - explicit Ceiling(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/ceiling_layout.h b/poincare/include/poincare/ceiling_layout.h index 72ce65484..8b06304e7 100644 --- a/poincare/include/poincare/ceiling_layout.h +++ b/poincare/include/poincare/ceiling_layout.h @@ -30,11 +30,8 @@ protected: class CeilingLayout final : public Layout { public: - static CeilingLayout Builder(Layout l) { return CeilingLayout(l); } -private: - explicit CeilingLayout(Layout l) : Layout(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, l); - } + static CeilingLayout Builder(Layout l); + CeilingLayout() = delete; }; } diff --git a/poincare/include/poincare/char_layout.h b/poincare/include/poincare/char_layout.h index aa183db36..c206d39b8 100644 --- a/poincare/include/poincare/char_layout.h +++ b/poincare/include/poincare/char_layout.h @@ -17,10 +17,8 @@ public: {} // CharLayout - virtual void setChar(char c) { m_char = c; } char character() const { return m_char; } const KDFont * font() const { return m_font; } - void setFont(const KDFont * font) { m_font = font; } // LayoutNode void moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout) override; @@ -62,7 +60,7 @@ private: class CharLayout final : public Layout { public: CharLayout(const CharLayoutNode * n) : Layout(n) {} - CharLayout(char c, const KDFont * font = KDFont::LargeFont); + static CharLayout Builder(char c, const KDFont * font = KDFont::LargeFont); const KDFont * font() const { return const_cast(this)->node()->font(); } char character() const {return const_cast(this)->node()->character();} private: diff --git a/poincare/include/poincare/complex.h b/poincare/include/poincare/complex.h index 9d443ea65..1f9e82652 100644 --- a/poincare/include/poincare/complex.h +++ b/poincare/include/poincare/complex.h @@ -9,9 +9,9 @@ template class Complex; template -class ComplexNode final : public std::complex, public EvaluationNode { +class ComplexNode final : public EvaluationNode, public std::complex { public: - ComplexNode() : std::complex(NAN, NAN) {} + ComplexNode(std::complex c); // TreeNode size_t size() const override { return sizeof(ComplexNode); } @@ -26,7 +26,6 @@ public: } #endif - virtual void setComplex(std::complex c); typename Poincare::EvaluationNode::Type type() const override { return Poincare::EvaluationNode::Type::Complex; } bool isUndefined() const override { return (std::isnan(this->real()) && std::isnan(this->imag())); @@ -41,10 +40,10 @@ template class Complex final : public Evaluation { public: Complex(ComplexNode * n) : Evaluation(n) {} - explicit Complex(T a, T b = 0.0) : Complex(std::complex(a, b)) {} - explicit Complex(std::complex c); + static Complex Builder(std::complex c); + static Complex Builder(T a, T b = 0.0) { return Complex::Builder(std::complex(a, b)); } static Complex Undefined() { - return Complex(NAN, NAN); + return Complex::Builder(NAN, NAN); } std::complex stdComplex() { return *node(); } T real() { return node()->real(); } diff --git a/poincare/include/poincare/complex_argument.h b/poincare/include/poincare/complex_argument.h index c770ed433..9ec2bec09 100644 --- a/poincare/include/poincare/complex_argument.h +++ b/poincare/include/poincare/complex_argument.h @@ -41,15 +41,11 @@ private: class ComplexArgument final : public Expression { public: ComplexArgument(const ComplexArgumentNode * n) : Expression(n) {} - static ComplexArgument Builder(Expression child) { return ComplexArgument(child); } + static ComplexArgument Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("arg", 1, &UntypedBuilder); Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); -private: - explicit ComplexArgument(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/complex_cartesian.h b/poincare/include/poincare/complex_cartesian.h index e86835e64..4a6db764f 100644 --- a/poincare/include/poincare/complex_cartesian.h +++ b/poincare/include/poincare/complex_cartesian.h @@ -38,8 +38,8 @@ class ComplexCartesian final : public Expression { public: ComplexCartesian() : Expression() {} ComplexCartesian(const ComplexCartesianNode * node) : Expression(node) {} - static ComplexCartesian Builder() { ComplexCartesianNode * node = TreePool::sharedPool()->createTreeNode(); return ComplexCartesian(node); } - static ComplexCartesian Builder(Expression child0, Expression child1) { return ComplexCartesian(child0, child1); } + static ComplexCartesian Builder(); + static ComplexCartesian Builder(Expression child0, Expression child1); // Getters Expression real() { return childAtIndex(0); } @@ -60,10 +60,6 @@ public: ComplexCartesian power(ComplexCartesian & other, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); private: static constexpr int k_maxNumberOfNodesBeforeInterrupting = 50; - ComplexCartesian(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child0); - replaceChildAtIndexInPlace(1, child1); - } void factorAndArgumentOfFunction(Expression e, ExpressionNode::Type searchedType, Expression * factor, Expression * argument, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); ComplexCartesian interruptComputationIfManyNodes(); static Multiplication squareRootHelper(Expression e, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); diff --git a/poincare/include/poincare/condensed_sum_layout.h b/poincare/include/poincare/condensed_sum_layout.h index 59d2f6a7c..9c95a20d9 100644 --- a/poincare/include/poincare/condensed_sum_layout.h +++ b/poincare/include/poincare/condensed_sum_layout.h @@ -51,15 +51,8 @@ private: class CondensedSumLayout final : public Layout { public: - static CondensedSumLayout Builder(Layout base, Layout subscript, Layout superscript) { return CondensedSumLayout(base, subscript, superscript); } -private: - CondensedSumLayout(Layout base, Layout subscript, Layout superscript) : - Layout(TreePool::sharedPool()->createTreeNode()) - { - replaceChildAtIndexInPlace(0, base); - replaceChildAtIndexInPlace(1, subscript); - replaceChildAtIndexInPlace(2, superscript); - } + static CondensedSumLayout Builder(Layout base, Layout subscript, Layout superscript); + CondensedSumLayout() = delete; }; } diff --git a/poincare/include/poincare/confidence_interval.h b/poincare/include/poincare/confidence_interval.h index 30eda3893..88c82fc79 100644 --- a/poincare/include/poincare/confidence_interval.h +++ b/poincare/include/poincare/confidence_interval.h @@ -45,31 +45,22 @@ class ConfidenceInterval : public Expression { friend class SimplePredictionInterval; public: ConfidenceInterval(const ConfidenceIntervalNode * n) : Expression(n) {} - static ConfidenceInterval Builder(Expression child0, Expression child1) { return ConfidenceInterval(child0, child1); } + static ConfidenceInterval Builder(Expression child0, Expression child1); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("confidence", 2, &UntypedBuilder); // Expression Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); private: - ConfidenceInterval(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child0); - replaceChildAtIndexInPlace(1, child1); - } constexpr static int k_maxNValue = 300; }; class SimplePredictionInterval final : public ConfidenceInterval { public: SimplePredictionInterval(const SimplePredictionIntervalNode * n) : ConfidenceInterval(n) {} - static SimplePredictionInterval Builder(Expression child0, Expression child1) { return SimplePredictionInterval(child0, child1); } + static SimplePredictionInterval Builder(Expression child0, Expression child1); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("prediction", 2, &UntypedBuilder); -private: - SimplePredictionInterval(Expression child0, Expression child1) : ConfidenceInterval(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child0); - replaceChildAtIndexInPlace(1, child1); - } }; } diff --git a/poincare/include/poincare/conjugate.h b/poincare/include/poincare/conjugate.h index ac465b4cc..f6a0a1cb4 100644 --- a/poincare/include/poincare/conjugate.h +++ b/poincare/include/poincare/conjugate.h @@ -41,15 +41,11 @@ private: class Conjugate final : public Expression { public: Conjugate(const ConjugateNode * n) : Expression(n) {} - static Conjugate Builder(Expression child) { return Conjugate(child); } + static Conjugate Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("conj", 1, &UntypedBuilder);; Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); -private: - explicit Conjugate(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/conjugate_layout.h b/poincare/include/poincare/conjugate_layout.h index d95dde4f7..fe0bf5ea9 100644 --- a/poincare/include/poincare/conjugate_layout.h +++ b/poincare/include/poincare/conjugate_layout.h @@ -40,11 +40,8 @@ private: class ConjugateLayout final : public Layout { public: - static ConjugateLayout Builder(Layout l) { return ConjugateLayout(l); } -private: - explicit ConjugateLayout(Layout l) : Layout(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, l); - } + static ConjugateLayout Builder(Layout child); + ConjugateLayout() = delete; }; } diff --git a/poincare/include/poincare/constant.h b/poincare/include/poincare/constant.h index c5c529b87..c0754357c 100644 --- a/poincare/include/poincare/constant.h +++ b/poincare/include/poincare/constant.h @@ -7,6 +7,8 @@ namespace Poincare { class ConstantNode final : public SymbolAbstractNode { public: + ConstantNode(const char * newName, int length); + const char * name() const override { return m_name; } // TreeNode @@ -52,8 +54,8 @@ private: class Constant final : public SymbolAbstract { public: - Constant(char name); Constant(const ConstantNode * node) : SymbolAbstract(node) {} + static Constant Builder(char name); // Constant properties bool isPi() const { return node()->isPi(); } diff --git a/poincare/include/poincare/cosine.h b/poincare/include/poincare/cosine.h index 060384a0b..3e0524a65 100644 --- a/poincare/include/poincare/cosine.h +++ b/poincare/include/poincare/cosine.h @@ -46,15 +46,11 @@ private: class Cosine final : public Expression { public: Cosine(const CosineNode * n) : Expression(n) {} - static Cosine Builder(Expression child) { return Cosine(child); } + static Cosine Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("cos", 1, &UntypedBuilder); Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); -private: - explicit Cosine(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/decimal.h b/poincare/include/poincare/decimal.h index 22971bb8c..e55904fc7 100644 --- a/poincare/include/poincare/decimal.h +++ b/poincare/include/poincare/decimal.h @@ -18,19 +18,13 @@ class Decimal; class DecimalNode final : public NumberNode { friend class Decimal; public: - DecimalNode() : - m_negative(false), - m_exponent(0), - m_numberOfDigitsInMantissa(0) {} - - virtual void setValue(const native_uint_t * mantissaDigits, uint8_t mantissaSize, int exponent, bool negative); + DecimalNode(const native_uint_t * mantissaDigits, uint8_t mantissaSize, int exponent, bool negative); Integer signedMantissa() const; Integer unsignedMantissa() const; int exponent() const { return m_exponent; } // TreeNode - void initToMatchSize(size_t size) override; size_t size() const override; #if POINCARE_TREE_LOG virtual void logNodeName(std::ostream & stream) const override { @@ -52,10 +46,10 @@ public: // Approximation Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { - return Complex(templatedApproximate()); + return Complex::Builder(templatedApproximate()); } Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { - return Complex(templatedApproximate()); + return Complex::Builder(templatedApproximate()); } // Comparison @@ -88,11 +82,12 @@ friend class DecimalNode; template friend class ComplexNode; public: - static int Exponent(const char * integralPart, int integralPartLength, const char * fractionalPart, int fractionalPartLength, const char * exponent, int exponentLength, bool exponentIsNegative = false); - Decimal(const char * integralPart, int integralPartLength, const char * fractionalPart, int fractionalPartLength, int exponent); Decimal(DecimalNode * node) : Number(node) {} - Decimal(Integer m, int e); - template Decimal(T f); + static Decimal Builder(const char * integralPart, int integralPartLength, const char * fractionalPart, int fractionalPartLength, int exponent); + static Decimal Builder(Integer m, int e); + template static Decimal Builder(T f); + static int Exponent(const char * integralPart, int integralPartLength, const char * fractionalPart, int fractionalPartLength, const char * exponent, int exponentLength, bool exponentIsNegative = false); + /* k_maxExponentLength caps the string length we parse to create the exponent. * It prevents m_exponent (int32_t) from overflowing and giving wrong results. */ constexpr static int k_maxExponentLength = 8; @@ -101,7 +96,7 @@ public: private: constexpr static int k_maxMantissaLength = 20; DecimalNode * node() const { return static_cast(Number::node()); } - Decimal(size_t size, const Integer & m, int e); + static Decimal Builder(size_t size, const Integer & m, int e); Expression setSign(ExpressionNode::Sign s); // Simplification Expression shallowReduce(); diff --git a/poincare/include/poincare/derivative.h b/poincare/include/poincare/derivative.h index 4bb534b37..70dc0973a 100644 --- a/poincare/include/poincare/derivative.h +++ b/poincare/include/poincare/derivative.h @@ -51,7 +51,7 @@ private: class Derivative final : public Expression { public: Derivative(const DerivativeNode * n) : Expression(n) {} - static Derivative Builder(Expression child0, Symbol child1, Expression child2) { return Derivative(child0, child1, child2); } + static Derivative Builder(Expression child0, Symbol child1, Expression child2); static Expression UntypedBuilder(Expression children) { if (children.childAtIndex(1).type() != ExpressionNode::Type::Symbol) { // Second parameter must be a Symbol. @@ -62,13 +62,6 @@ public: static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("diff", 3, &UntypedBuilder); Expression shallowReduce(); -private: - Derivative(Expression child0, Expression child1, Expression child2) : Expression(TreePool::sharedPool()->createTreeNode()) { - assert(child1.type() == ExpressionNode::Type::Symbol); - replaceChildAtIndexInPlace(0, child0); - replaceChildAtIndexInPlace(1, child1); - replaceChildAtIndexInPlace(2, child2); - } }; } diff --git a/poincare/include/poincare/determinant.h b/poincare/include/poincare/determinant.h index 8909acca7..ff350e1fd 100644 --- a/poincare/include/poincare/determinant.h +++ b/poincare/include/poincare/determinant.h @@ -35,15 +35,11 @@ private: class Determinant final : public Expression { public: Determinant(const DeterminantNode * n) : Expression(n) {} - static Determinant Builder(Expression child) { return Determinant(child); } + static Determinant Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("det", 1, &UntypedBuilder); Expression shallowReduce(Context & context); -private: - explicit Determinant(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/division.h b/poincare/include/poincare/division.h index b620eba3d..c1bf207b5 100644 --- a/poincare/include/poincare/division.h +++ b/poincare/include/poincare/division.h @@ -61,18 +61,10 @@ private: class Division final : public Expression { public: Division(const DivisionNode * n) : Expression(n) {} - static Division Builder() { return Division(); } - static Division Builder(Expression numerator, Expression denominator) { - Division d; - d.replaceChildAtIndexInPlace(0, numerator); - d.replaceChildAtIndexInPlace(1, denominator); - return d; - } + static Division Builder(); + static Division Builder(Expression numerator, Expression denominator); Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - -private: - Division() : Expression(TreePool::sharedPool()->createTreeNode()) {} }; } diff --git a/poincare/include/poincare/division_quotient.h b/poincare/include/poincare/division_quotient.h index 170eaf74a..d6f358a73 100644 --- a/poincare/include/poincare/division_quotient.h +++ b/poincare/include/poincare/division_quotient.h @@ -38,17 +38,12 @@ private: class DivisionQuotient final : public Expression { public: DivisionQuotient(const DivisionQuotientNode * n) : Expression(n) {} - static DivisionQuotient Builder(Expression child0, Expression child1) { return DivisionQuotient(child0, child1); } + static DivisionQuotient Builder(Expression child0, Expression child1); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("quo", 2, &UntypedBuilder); // Expression Expression shallowReduce(); -private: - DivisionQuotient(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child0); - replaceChildAtIndexInPlace(1, child1); - } }; } diff --git a/poincare/include/poincare/division_remainder.h b/poincare/include/poincare/division_remainder.h index 07443c5d2..b7a3e1273 100644 --- a/poincare/include/poincare/division_remainder.h +++ b/poincare/include/poincare/division_remainder.h @@ -39,17 +39,12 @@ private: class DivisionRemainder final : public Expression { public: DivisionRemainder(const DivisionRemainderNode * n) : Expression(n) {} - static DivisionRemainder Builder(Expression child0, Expression child1) { return DivisionRemainder(child0, child1); } + static DivisionRemainder Builder(Expression child0, Expression child1); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("rem", 2, &UntypedBuilder); // Expression Expression shallowReduce(); -private: - DivisionRemainder(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child0); - replaceChildAtIndexInPlace(1, child1); - } }; } diff --git a/poincare/include/poincare/empty_expression.h b/poincare/include/poincare/empty_expression.h index 0f67887b6..332430992 100644 --- a/poincare/include/poincare/empty_expression.h +++ b/poincare/include/poincare/empty_expression.h @@ -33,7 +33,7 @@ private: class EmptyExpression final : public Expression { public: - EmptyExpression(); + static EmptyExpression Builder(); EmptyExpression(const EmptyExpressionNode * n) : Expression(n) {} }; diff --git a/poincare/include/poincare/empty_layout.h b/poincare/include/poincare/empty_layout.h index 9cb5ea312..cc07406bb 100644 --- a/poincare/include/poincare/empty_layout.h +++ b/poincare/include/poincare/empty_layout.h @@ -26,8 +26,6 @@ public: void setColor(Color color) { m_color = color; } bool isVisible() const { return m_isVisible; } void setVisible(bool visible) { m_isVisible = visible; } - void setMargins(bool margins) { m_margins = margins; } - void setFont(const KDFont * font) { m_font = font; } // LayoutNode void deleteBeforeCursor(LayoutCursor * cursor) override; @@ -75,7 +73,7 @@ private: class EmptyLayout final : public Layout { public: EmptyLayout(const EmptyLayoutNode * n); - EmptyLayout(EmptyLayoutNode::Color color = EmptyLayoutNode::Color::Yellow, bool visible = true, const KDFont * font = KDFont::LargeFont, bool margins = true); + static EmptyLayout Builder(EmptyLayoutNode::Color color = EmptyLayoutNode::Color::Yellow, bool visible = true, const KDFont * font = KDFont::LargeFont, bool margins = true); void setVisible(bool visible) { node()->setVisible(visible); } diff --git a/poincare/include/poincare/equal.h b/poincare/include/poincare/equal.h index 6b91f2d62..e191b12ba 100644 --- a/poincare/include/poincare/equal.h +++ b/poincare/include/poincare/equal.h @@ -35,10 +35,7 @@ private: class Equal final : public Expression { public: Equal(const EqualNode * n) : Expression(n) {} - Equal(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child0); - replaceChildAtIndexInPlace(1, child1); - } + static Equal Builder(Expression child0, Expression child1); // For the equation A = B, create the reduced expression A-B Expression standardEquation(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; diff --git a/poincare/include/poincare/factor.h b/poincare/include/poincare/factor.h index 401a90126..09ebcbf6a 100644 --- a/poincare/include/poincare/factor.h +++ b/poincare/include/poincare/factor.h @@ -37,16 +37,12 @@ private: class Factor final : public Expression { public: Factor(const FactorNode * n) : Expression(n) {} - static Factor Builder(Expression child) { return Factor(child); } + static Factor Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("factor", 1, &UntypedBuilder); Expression shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); Multiplication createMultiplicationOfIntegerPrimeDecomposition(Integer i, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; -private: - explicit Factor(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/factorial.h b/poincare/include/poincare/factorial.h index 2a1f2774d..c76129c69 100644 --- a/poincare/include/poincare/factorial.h +++ b/poincare/include/poincare/factorial.h @@ -52,18 +52,13 @@ private: class Factorial final : public Expression { public: Factorial(const FactorialNode * n) : Expression(n) {} - static Factorial Builder() { return Factorial(); } - static Factorial Builder(Expression child) { - Factorial f; - f.replaceChildAtIndexInPlace(0, child); - return f; - } + static Factorial Builder(); + static Factorial Builder(Expression child); Expression shallowReduce(); Expression shallowBeautify(); private: constexpr static int k_maxOperandValue = 100; - Factorial() : Expression(TreePool::sharedPool()->createTreeNode()) {} }; } diff --git a/poincare/include/poincare/float.h b/poincare/include/poincare/float.h index 039a967ad..9ecdaab70 100644 --- a/poincare/include/poincare/float.h +++ b/poincare/include/poincare/float.h @@ -20,10 +20,8 @@ namespace Poincare { template class FloatNode final : public NumberNode { public: - FloatNode() : m_value(0.0) {} + FloatNode(T value = 0.0) : m_value(value) {} - - void setFloat(T a) { m_value = a; } T value() const { return m_value; } // TreeNode @@ -52,7 +50,7 @@ public: Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } private: template Evaluation templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { - return Complex((U)m_value); + return Complex::Builder((U)m_value); } T m_value; }; @@ -60,7 +58,7 @@ private: template class Float final : public Number { public: - Float(T value); + static Float Builder(T value); private: FloatNode * node() const { return static_cast *>(Number::node()); } }; diff --git a/poincare/include/poincare/floor.h b/poincare/include/poincare/floor.h index 7a823747f..507ecb541 100644 --- a/poincare/include/poincare/floor.h +++ b/poincare/include/poincare/floor.h @@ -44,15 +44,11 @@ private: class Floor final : public Expression { public: Floor(const FloorNode * n) : Expression(n) {} - static Floor Builder(Expression child) { return Floor(child); } + static Floor Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("floor", 1, &UntypedBuilder); Expression shallowReduce(); -private: - explicit Floor(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/floor_layout.h b/poincare/include/poincare/floor_layout.h index 7caf67ed0..77ee2b986 100644 --- a/poincare/include/poincare/floor_layout.h +++ b/poincare/include/poincare/floor_layout.h @@ -29,11 +29,8 @@ protected: class FloorLayout final : public Layout { public: - static FloorLayout Builder(Layout l) { return FloorLayout(l); } -private: - explicit FloorLayout(Layout l) : Layout(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, l); - } + static FloorLayout Builder(Layout child); + FloorLayout() = delete; }; } diff --git a/poincare/include/poincare/frac_part.h b/poincare/include/poincare/frac_part.h index 9988621c1..f6551e063 100644 --- a/poincare/include/poincare/frac_part.h +++ b/poincare/include/poincare/frac_part.h @@ -44,15 +44,11 @@ private: class FracPart final : public Expression { public: FracPart(const FracPartNode * n) : Expression(n) {} - static FracPart Builder(Expression child) { return FracPart(child); } + static FracPart Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("frac", 1, &UntypedBuilder); Expression shallowReduce(); -private: - explicit FracPart(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/fraction_layout.h b/poincare/include/poincare/fraction_layout.h index 23ee39f8f..17df46c28 100644 --- a/poincare/include/poincare/fraction_layout.h +++ b/poincare/include/poincare/fraction_layout.h @@ -58,14 +58,8 @@ private: class FractionLayout final : public Layout { public: - static FractionLayout Builder(Layout numerator, Layout denominator) { return FractionLayout(numerator, denominator); } -private: - FractionLayout(Layout numerator, Layout denominator) : - Layout(TreePool::sharedPool()->createTreeNode()) - { - replaceChildAtIndexInPlace(0, numerator); - replaceChildAtIndexInPlace(1, denominator); - } + static FractionLayout Builder(Layout numerator, Layout denominator); + FractionLayout() = delete; }; } diff --git a/poincare/include/poincare/function.h b/poincare/include/poincare/function.h index c12bc6896..781324826 100644 --- a/poincare/include/poincare/function.h +++ b/poincare/include/poincare/function.h @@ -8,6 +8,8 @@ namespace Poincare { class FunctionNode : public SymbolAbstractNode { public: + FunctionNode(const char * newName, int length); + // SymbolAbstractNode const char * name() const override { return m_name; } @@ -49,15 +51,12 @@ private: class Function : public SymbolAbstract { friend class FunctionNode; public: - Function(const char * name, size_t length); Function(const FunctionNode * n) : SymbolAbstract(n) {} - Function(const char * name, size_t length, Expression child) : Function(name, length) { - replaceChildAtIndexInPlace(0, child); - } + static Function Builder(const char * name, size_t length, Expression child = Expression()); static Expression UntypedBuilder(const char * name, size_t length, Expression child, Context * context) { /* Create an expression only if it is not in the context or defined as a * function */ - Function f(name, length, child); + Function f = Function::Builder(name, length, child); if (SymbolAbstract::ValidInContext(f, context)) { return f; } diff --git a/poincare/include/poincare/ghost.h b/poincare/include/poincare/ghost.h index d27eff5e9..da30640df 100644 --- a/poincare/include/poincare/ghost.h +++ b/poincare/include/poincare/ghost.h @@ -12,9 +12,12 @@ namespace Poincare { class Ghost final : public TreeHandle { public: - static Ghost Builder() { return Ghost(); } -private: - Ghost() : TreeHandle(TreePool::sharedPool()->createTreeNode()) {} + static Ghost Builder() { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(GhostNode)); + GhostNode * node = new (bufferNode) GhostNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); + } }; } diff --git a/poincare/include/poincare/great_common_divisor.h b/poincare/include/poincare/great_common_divisor.h index b392fede9..019867025 100644 --- a/poincare/include/poincare/great_common_divisor.h +++ b/poincare/include/poincare/great_common_divisor.h @@ -37,17 +37,12 @@ private: class GreatCommonDivisor final : public Expression { public: GreatCommonDivisor(const GreatCommonDivisorNode * n) : Expression(n) {} - static GreatCommonDivisor Builder(Expression child0, Expression child1) { return GreatCommonDivisor(child0, child1); } + static GreatCommonDivisor Builder(Expression child0, Expression child1); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("gcd", 2, &UntypedBuilder); // Expression Expression shallowReduce(); -private: - GreatCommonDivisor(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child0); - replaceChildAtIndexInPlace(1, child1); - } }; } diff --git a/poincare/include/poincare/grid_layout.h b/poincare/include/poincare/grid_layout.h index 46e0b8e2e..9510c75f9 100644 --- a/poincare/include/poincare/grid_layout.h +++ b/poincare/include/poincare/grid_layout.h @@ -89,7 +89,7 @@ private: class GridLayout : public Layout { public: GridLayout(const GridLayoutNode * n) : Layout(n) {} - static GridLayout Builder() { return GridLayout(); } + static GridLayout Builder(); void setDimensions(int rows, int columns); void addChildAtIndex(Layout l, int index, int currentNumberOfChildren, LayoutCursor * cursor) { Layout::addChildAtIndex(l, index, currentNumberOfChildren, cursor); @@ -97,7 +97,6 @@ public: int numberOfRows() const { return node()->numberOfRows(); } int numberOfColumns() const { return node()->numberOfColumns(); } private: - GridLayout() : Layout(TreePool::sharedPool()->createTreeNode()) {} virtual GridLayoutNode * node() const { return static_cast(Layout::node()); } void setNumberOfRows(int rows) { assert(rows >= 0); diff --git a/poincare/include/poincare/horizontal_layout.h b/poincare/include/poincare/horizontal_layout.h index 5cb32b211..2b39ecd29 100644 --- a/poincare/include/poincare/horizontal_layout.h +++ b/poincare/include/poincare/horizontal_layout.h @@ -68,7 +68,7 @@ class HorizontalLayout final : public Layout { public: // Constructors HorizontalLayout(HorizontalLayoutNode * n) : Layout(n) {} - static HorizontalLayout Builder() { return HorizontalLayout(); } + static HorizontalLayout Builder(); static HorizontalLayout Builder(Layout l) { return HorizontalLayout::Builder(&l, 1); } static HorizontalLayout Builder(Layout l1, Layout l2) { return HorizontalLayout::Builder(ArrayBuilder(l1, l2).array(), 2); } static HorizontalLayout Builder(Layout l1, Layout l2, Layout l3) { return HorizontalLayout::Builder(ArrayBuilder(l1, l2, l3).array(), 3); } @@ -93,7 +93,6 @@ public: void mergeChildrenAtIndex(HorizontalLayout h, int index, bool removeEmptyChildren, LayoutCursor * cursor = nullptr); private: - HorizontalLayout() : Layout(TreePool::sharedPool()->createTreeNode()) {} void removeEmptyChildBeforeInsertionAtIndex(int * index, int * currentNumberOfChildren, bool shouldRemoveOnLeft, LayoutCursor * cursor = nullptr); }; diff --git a/poincare/include/poincare/hyperbolic_arc_cosine.h b/poincare/include/poincare/hyperbolic_arc_cosine.h index aebd357ef..8f8a8272f 100644 --- a/poincare/include/poincare/hyperbolic_arc_cosine.h +++ b/poincare/include/poincare/hyperbolic_arc_cosine.h @@ -36,13 +36,9 @@ private: class HyperbolicArcCosine final : public HyperbolicTrigonometricFunction { public: HyperbolicArcCosine(const HyperbolicArcCosineNode * n) : HyperbolicTrigonometricFunction(n) {} - static HyperbolicArcCosine Builder(Expression child) { return HyperbolicArcCosine(child); } + static HyperbolicArcCosine Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("acosh", 1, &UntypedBuilder); -private: - explicit HyperbolicArcCosine(Expression child) : HyperbolicTrigonometricFunction(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/hyperbolic_arc_sine.h b/poincare/include/poincare/hyperbolic_arc_sine.h index fd7ec2644..0569275c2 100644 --- a/poincare/include/poincare/hyperbolic_arc_sine.h +++ b/poincare/include/poincare/hyperbolic_arc_sine.h @@ -36,13 +36,9 @@ private: class HyperbolicArcSine final : public HyperbolicTrigonometricFunction { public: HyperbolicArcSine(const HyperbolicArcSineNode * n) : HyperbolicTrigonometricFunction(n) {} - static HyperbolicArcSine Builder(Expression child) { return HyperbolicArcSine(child); } + static HyperbolicArcSine Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("asinh", 1, &UntypedBuilder); -private: - explicit HyperbolicArcSine(Expression child) : HyperbolicTrigonometricFunction(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/hyperbolic_arc_tangent.h b/poincare/include/poincare/hyperbolic_arc_tangent.h index 01bfe38ab..565fcb42f 100644 --- a/poincare/include/poincare/hyperbolic_arc_tangent.h +++ b/poincare/include/poincare/hyperbolic_arc_tangent.h @@ -36,13 +36,9 @@ private: class HyperbolicArcTangent final : public HyperbolicTrigonometricFunction { public: HyperbolicArcTangent(const HyperbolicArcTangentNode * n) : HyperbolicTrigonometricFunction(n) {} - static HyperbolicArcTangent Builder(Expression child) { return HyperbolicArcTangent(child); } + static HyperbolicArcTangent Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("atanh", 1, &UntypedBuilder); -private: - explicit HyperbolicArcTangent(Expression child) : HyperbolicTrigonometricFunction(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/hyperbolic_cosine.h b/poincare/include/poincare/hyperbolic_cosine.h index 6764d1948..cbe78f7ba 100644 --- a/poincare/include/poincare/hyperbolic_cosine.h +++ b/poincare/include/poincare/hyperbolic_cosine.h @@ -36,13 +36,9 @@ private: class HyperbolicCosine final : public HyperbolicTrigonometricFunction { public: HyperbolicCosine(const HyperbolicCosineNode * n) : HyperbolicTrigonometricFunction(n) {} - static HyperbolicCosine Builder(Expression child) { return HyperbolicCosine(child); } + static HyperbolicCosine Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("cosh", 1, &UntypedBuilder); -private: - explicit HyperbolicCosine(Expression child) : HyperbolicTrigonometricFunction(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/hyperbolic_sine.h b/poincare/include/poincare/hyperbolic_sine.h index 2acdc7dd7..53cf3eb85 100644 --- a/poincare/include/poincare/hyperbolic_sine.h +++ b/poincare/include/poincare/hyperbolic_sine.h @@ -36,13 +36,9 @@ private: class HyperbolicSine final : public HyperbolicTrigonometricFunction { public: HyperbolicSine(const HyperbolicSineNode * n) : HyperbolicTrigonometricFunction(n) {} - static HyperbolicSine Builder(Expression child) { return HyperbolicSine(child); } + static HyperbolicSine Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("sinh", 1, &UntypedBuilder); -private: - explicit HyperbolicSine(Expression child) : HyperbolicTrigonometricFunction(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/hyperbolic_tangent.h b/poincare/include/poincare/hyperbolic_tangent.h index d6d887c2e..cc43e572b 100644 --- a/poincare/include/poincare/hyperbolic_tangent.h +++ b/poincare/include/poincare/hyperbolic_tangent.h @@ -36,13 +36,9 @@ private: class HyperbolicTangent final : public HyperbolicTrigonometricFunction { public: HyperbolicTangent(const HyperbolicTangentNode * n) : HyperbolicTrigonometricFunction(n) {} - static HyperbolicTangent Builder(Expression child) { return HyperbolicTangent(child); } + static HyperbolicTangent Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("tanh", 1, &UntypedBuilder); -private: - explicit HyperbolicTangent(Expression child) : HyperbolicTrigonometricFunction(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/imaginary_part.h b/poincare/include/poincare/imaginary_part.h index 06956b66d..3fda87d4e 100644 --- a/poincare/include/poincare/imaginary_part.h +++ b/poincare/include/poincare/imaginary_part.h @@ -32,7 +32,7 @@ private: Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { - return Complex(std::imag(c)); + return Complex::Builder(std::imag(c)); } Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); @@ -45,15 +45,11 @@ private: class ImaginaryPart final : public Expression { public: ImaginaryPart(const ImaginaryPartNode * n) : Expression(n) {} - static ImaginaryPart Builder(Expression child) { return ImaginaryPart(child); } + static ImaginaryPart Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("im", 1, &UntypedBuilder); Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); -private: - explicit ImaginaryPart(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/infinity.h b/poincare/include/poincare/infinity.h index a88ecee04..b1b552394 100644 --- a/poincare/include/poincare/infinity.h +++ b/poincare/include/poincare/infinity.h @@ -7,8 +7,8 @@ namespace Poincare { class InfinityNode final : public NumberNode { public: + InfinityNode(bool negative) : NumberNode(), m_negative(negative) {} - void setNegative(bool negative) { m_negative = negative; } Expression setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; // TreeNode @@ -45,9 +45,7 @@ private: class Infinity final : public Number { public: Infinity(InfinityNode * n) : Number(n) {} - Infinity(bool negative) : Number(TreePool::sharedPool()->createTreeNode()) { - node()->setNegative(negative); - } + static Infinity Builder(bool negative); Expression setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); static const char * Name() { return "inf"; diff --git a/poincare/include/poincare/integer.h b/poincare/include/poincare/integer.h index 61ebcf47e..11aea50db 100644 --- a/poincare/include/poincare/integer.h +++ b/poincare/include/poincare/integer.h @@ -31,8 +31,8 @@ struct IntegerDivision; class IntegerNode final : public TreeNode { public: + IntegerNode(const native_uint_t * digits, uint8_t numberOfDigits); // TreeNode - void initToMatchSize(size_t goalSize) override; size_t size() const override; int numberOfChildren() const override { return 0; } #if POINCARE_TREE_LOG @@ -43,7 +43,6 @@ public: virtual void logAttributes(std::ostream & stream) const override; #endif - virtual void setDigits(const native_uint_t * digits, uint8_t numberOfDigits); const native_uint_t * digits() const { return m_digits; } uint8_t numberOfDigits() const { return m_numberOfDigits; } private: diff --git a/poincare/include/poincare/integral.h b/poincare/include/poincare/integral.h index 195b7647a..403a41b13 100644 --- a/poincare/include/poincare/integral.h +++ b/poincare/include/poincare/integral.h @@ -55,7 +55,7 @@ private: class Integral final : public Expression { public: Integral(const IntegralNode * n) : Expression(n) {} - static Integral Builder(Expression child0, Symbol child1, Expression child2, Expression child3) { return Integral(child0, child1, child2, child3); } + static Integral Builder(Expression child0, Symbol child1, Expression child2, Expression child3); static Expression UntypedBuilder(Expression children) { if (children.childAtIndex(1).type() != ExpressionNode::Type::Symbol) { // Second parameter must be a Symbol. @@ -67,14 +67,6 @@ public: // Expression Expression shallowReduce(); -private: - Integral(Expression child0, Expression child1, Expression child2, Expression child3) : Expression(TreePool::sharedPool()->createTreeNode()) { - assert(child1.type() == ExpressionNode::Type::Symbol); - replaceChildAtIndexInPlace(0, child0); - replaceChildAtIndexInPlace(1, child1); - replaceChildAtIndexInPlace(2, child2); - replaceChildAtIndexInPlace(3, child3); - } }; } diff --git a/poincare/include/poincare/integral_layout.h b/poincare/include/poincare/integral_layout.h index 26fc711a0..79f6e8a73 100644 --- a/poincare/include/poincare/integral_layout.h +++ b/poincare/include/poincare/integral_layout.h @@ -56,16 +56,8 @@ private: class IntegralLayout final : public Layout { public: - static IntegralLayout Builder(Layout integrand, Layout differential, Layout lowerBound, Layout upperBound) { return IntegralLayout(integrand, differential, lowerBound, upperBound); } -private: - IntegralLayout(Layout integrand, Layout differential, Layout lowerBound, Layout upperBound) : - Layout(TreePool::sharedPool()->createTreeNode()) - { - replaceChildAtIndexInPlace(0, integrand); - replaceChildAtIndexInPlace(1, differential); - replaceChildAtIndexInPlace(2, lowerBound); - replaceChildAtIndexInPlace(3, upperBound); - } + static IntegralLayout Builder(Layout integrand, Layout differential, Layout lowerBound, Layout upperBound); + IntegralLayout() = delete; }; } diff --git a/poincare/include/poincare/least_common_multiple.h b/poincare/include/poincare/least_common_multiple.h index 9dcd9e114..4f2fcbe4f 100644 --- a/poincare/include/poincare/least_common_multiple.h +++ b/poincare/include/poincare/least_common_multiple.h @@ -37,17 +37,12 @@ private: class LeastCommonMultiple final : public Expression { public: LeastCommonMultiple(const LeastCommonMultipleNode * n) : Expression(n) {} - static LeastCommonMultiple Builder(Expression child0, Expression child1) { return LeastCommonMultiple(child0, child1); } + static LeastCommonMultiple Builder(Expression child0, Expression child1); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("lcm", 2, &UntypedBuilder); // Expression Expression shallowReduce(); -private: - LeastCommonMultiple(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child0); - replaceChildAtIndexInPlace(1, child1); - } }; } diff --git a/poincare/include/poincare/left_parenthesis_layout.h b/poincare/include/poincare/left_parenthesis_layout.h index 5bf6d25e0..66f52047b 100644 --- a/poincare/include/poincare/left_parenthesis_layout.h +++ b/poincare/include/poincare/left_parenthesis_layout.h @@ -35,9 +35,8 @@ protected: class LeftParenthesisLayout final : public Layout { public: - static LeftParenthesisLayout Builder() { return LeftParenthesisLayout(); } -private: - LeftParenthesisLayout() : Layout(TreePool::sharedPool()->createTreeNode()) {} + static LeftParenthesisLayout Builder(); + LeftParenthesisLayout() = delete; }; } diff --git a/poincare/include/poincare/left_square_bracket_layout.h b/poincare/include/poincare/left_square_bracket_layout.h index c0dfed6cd..558e69e3b 100644 --- a/poincare/include/poincare/left_square_bracket_layout.h +++ b/poincare/include/poincare/left_square_bracket_layout.h @@ -29,9 +29,8 @@ protected: class LeftSquareBracketLayout final : public Layout { public: - static LeftSquareBracketLayout Builder() { return LeftSquareBracketLayout(); } -private: - LeftSquareBracketLayout() : Layout(TreePool::sharedPool()->createTreeNode()) {} + static LeftSquareBracketLayout Builder(); + LeftSquareBracketLayout() = delete; }; } diff --git a/poincare/include/poincare/logarithm.h b/poincare/include/poincare/logarithm.h index 9bc82b5dd..c7c5e5902 100644 --- a/poincare/include/poincare/logarithm.h +++ b/poincare/include/poincare/logarithm.h @@ -34,7 +34,7 @@ public: /* log has a branch cut on ]-inf, 0]: it is then multivalued on this cut. We * followed the convention chosen by the lib c++ of llvm on ]-inf+0i, 0+0i] * (warning: log takes the other side of the cut values on ]-inf-0i, 0-0i]). */ - return Complex(std::log10(c)); + return Complex::Builder(std::log10(c)); } Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } @@ -44,7 +44,7 @@ public: class Logarithm final : public Expression { public: Logarithm(const LogarithmNode<2> * n) : Expression(n) {} - static Logarithm Builder(Expression child0, Expression child1) { return Logarithm(child0, child1); } + static Logarithm Builder(Expression child0, Expression child1); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("log", 2, &UntypedBuilder); @@ -52,10 +52,6 @@ public: Expression shallowBeautify(); private: - Logarithm(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode >()) { - replaceChildAtIndexInPlace(0, child0); - replaceChildAtIndexInPlace(1, child1); - } Expression simpleShallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); Integer simplifyLogarithmIntegerBaseInteger(Integer i, Integer & base, Addition & a, bool isDenominator); Expression splitLogarithmInteger(Integer i, bool isDenominator, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); @@ -65,15 +61,11 @@ private: class CommonLogarithm : public Expression { public: CommonLogarithm(const LogarithmNode<1> * n) : Expression(n) {} - static CommonLogarithm Builder(Expression child) { return CommonLogarithm(child); } + static CommonLogarithm Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("log", 1, &UntypedBuilder); Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); -private: - explicit CommonLogarithm(Expression child) : Expression(TreePool::sharedPool()->createTreeNode >()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/matrix.h b/poincare/include/poincare/matrix.h index 1c07e0708..790d7b556 100644 --- a/poincare/include/poincare/matrix.h +++ b/poincare/include/poincare/matrix.h @@ -63,7 +63,7 @@ class Matrix final : public Expression { friend class GlobalContext; public: Matrix(const MatrixNode * node) : Expression(node) {} - static Matrix Builder() { return Matrix(); } + static Matrix Builder(); void setDimensions(int rows, int columns); int numberOfRows() const { return node()->numberOfRows(); } @@ -85,7 +85,6 @@ public: Expression inverse(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; #endif private: - Matrix() : Matrix(TreePool::sharedPool()->createTreeNode()) {} // TODO: find another solution for inverse and determinant (avoid capping the matrix) static constexpr int k_maxNumberOfCoefficients = 100; diff --git a/poincare/include/poincare/matrix_complex.h b/poincare/include/poincare/matrix_complex.h index 83ddd941e..73a750a88 100644 --- a/poincare/include/poincare/matrix_complex.h +++ b/poincare/include/poincare/matrix_complex.h @@ -57,8 +57,8 @@ class MatrixComplex final : public Evaluation { friend class MatrixComplexNode; public: MatrixComplex(MatrixComplexNode * node) : Evaluation(node) {} - MatrixComplex(); - MatrixComplex(std::complex * operands, int numberOfRows, int numberOfColumns); + static MatrixComplex Builder(); + static MatrixComplex Builder(std::complex * operands, int numberOfRows, int numberOfColumns); static MatrixComplex Undefined(); static MatrixComplex createIdentity(int dim); MatrixComplex inverse() const { return node()->inverse(); } diff --git a/poincare/include/poincare/matrix_dimension.h b/poincare/include/poincare/matrix_dimension.h index 412072edd..5fc51803f 100644 --- a/poincare/include/poincare/matrix_dimension.h +++ b/poincare/include/poincare/matrix_dimension.h @@ -35,15 +35,11 @@ private: class MatrixDimension final : public Expression { public: MatrixDimension(const MatrixDimensionNode * n) : Expression(n) {} - static MatrixDimension Builder(Expression child) { return MatrixDimension(child); } + static MatrixDimension Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("dim", 1, &UntypedBuilder); Expression shallowReduce(); -private: - explicit MatrixDimension(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/matrix_inverse.h b/poincare/include/poincare/matrix_inverse.h index b4488c8c3..b03976fb4 100644 --- a/poincare/include/poincare/matrix_inverse.h +++ b/poincare/include/poincare/matrix_inverse.h @@ -34,15 +34,11 @@ private: class MatrixInverse final : public Expression { public: MatrixInverse(const MatrixInverseNode * n) : Expression(n) {} - static MatrixInverse Builder(Expression child) { return MatrixInverse(child); } + static MatrixInverse Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("inverse", 1, &UntypedBuilder); Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); -private: - explicit MatrixInverse(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/matrix_layout.h b/poincare/include/poincare/matrix_layout.h index 9f3420136..519c6c585 100644 --- a/poincare/include/poincare/matrix_layout.h +++ b/poincare/include/poincare/matrix_layout.h @@ -57,8 +57,8 @@ private: class MatrixLayout /*final*/ : public GridLayout { friend class MatrixLayoutNode; public: - static MatrixLayout Builder() { return MatrixLayout(); } MatrixLayout(const MatrixLayoutNode * n) : GridLayout(n) {} + static MatrixLayout Builder(); static MatrixLayout Builder(Layout l1, Layout l2, Layout l3, Layout l4) { MatrixLayout m = MatrixLayout::Builder(); m.addChildAtIndexInPlace(l1, 0, 0); @@ -73,7 +73,6 @@ public: void addGreySquares() { node()->addGreySquares(); } void removeGreySquares() { node()->removeGreySquares(); } private: - MatrixLayout() : GridLayout(TreePool::sharedPool()->createTreeNode()) {} MatrixLayoutNode * node() const { return static_cast(Layout::node()); } }; diff --git a/poincare/include/poincare/matrix_trace.h b/poincare/include/poincare/matrix_trace.h index 3590ae444..ac281b937 100644 --- a/poincare/include/poincare/matrix_trace.h +++ b/poincare/include/poincare/matrix_trace.h @@ -34,15 +34,11 @@ private: class MatrixTrace final : public Expression { public: MatrixTrace(const MatrixTraceNode * n) : Expression(n) {} - static MatrixTrace Builder(Expression child) { return MatrixTrace(child); } + static MatrixTrace Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("trace", 1, &UntypedBuilder); Expression shallowReduce(); -private: - explicit MatrixTrace(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/matrix_transpose.h b/poincare/include/poincare/matrix_transpose.h index fe7e98ce1..bf6c1d7ec 100644 --- a/poincare/include/poincare/matrix_transpose.h +++ b/poincare/include/poincare/matrix_transpose.h @@ -34,15 +34,11 @@ private: class MatrixTranspose final : public Expression { public: MatrixTranspose(const MatrixTransposeNode * n) : Expression(n) {} - static MatrixTranspose Builder(Expression child) { return MatrixTranspose(child); } + static MatrixTranspose Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("transpose", 1, &UntypedBuilder); Expression shallowReduce(); -private: - explicit MatrixTranspose(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/multiplication.h b/poincare/include/poincare/multiplication.h index b41bde2ce..9b4dba610 100644 --- a/poincare/include/poincare/multiplication.h +++ b/poincare/include/poincare/multiplication.h @@ -27,7 +27,7 @@ public: int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const override; // Approximation - template static Complex compute(const std::complex c, const std::complex d, Preferences::ComplexFormat complexFormat) { return Complex(c*d); } + template static Complex compute(const std::complex c, const std::complex d, Preferences::ComplexFormat complexFormat) { return Complex::Builder(c*d); } template static MatrixComplex computeOnComplexAndMatrix(const std::complex c, const MatrixComplex m, Preferences::ComplexFormat complexFormat) { return ApproximationHelper::ElementWiseOnMatrixComplexAndComplex(m, c, complexFormat, compute); } @@ -67,10 +67,10 @@ class Multiplication final : public NAryExpression { friend class Power; public: Multiplication(const MultiplicationNode * n) : NAryExpression(n) {} - static Multiplication Builder() { return Multiplication(); } - static Multiplication Builder(Expression e1) { return Multiplication(&e1, 1); } - static Multiplication Builder(Expression e1, Expression e2) { return Multiplication(ArrayBuilder(e1, e2).array(), 2); } - static Multiplication Builder(Expression e1, Expression e2, Expression e3) { return Multiplication(ArrayBuilder(e1, e2, e3).array(), 3); } + static Multiplication Builder(); + static Multiplication Builder(Expression e1) { return Multiplication::Builder(&e1, 1); } + static Multiplication Builder(Expression e1, Expression e2) { return Multiplication::Builder(ArrayBuilder(e1, e2).array(), 2); } + static Multiplication Builder(Expression e1, Expression e2, Expression e3) { return Multiplication::Builder(ArrayBuilder(e1, e2, e3).array(), 3); } template static void computeOnArrays(T * m, T * n, T * result, int mNumberOfColumns, int mNumberOfRows, int nNumberOfColumns); // Expression @@ -81,12 +81,8 @@ public: Expression denominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; private: // Constructors - Multiplication() : NAryExpression(TreePool::sharedPool()->createTreeNode()) {} - explicit Multiplication(Expression * children, size_t numberOfChildren) : Multiplication() { - for (size_t i = 0; i < numberOfChildren; i++) { - addChildAtIndexInPlace(children[i], i, i); - } - } + static Multiplication Builder(Expression * children, size_t numberOfChildren); + // Simplification Expression privateShallowReduce(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target, bool expand, bool canBeInterrupted); void mergeMultiplicationChildrenInPlace(); diff --git a/poincare/include/poincare/naperian_logarithm.h b/poincare/include/poincare/naperian_logarithm.h index 8e2409729..c880afe5a 100644 --- a/poincare/include/poincare/naperian_logarithm.h +++ b/poincare/include/poincare/naperian_logarithm.h @@ -31,7 +31,7 @@ private: /* ln has a branch cut on ]-inf, 0]: it is then multivalued on this cut. We * followed the convention chosen by the lib c++ of llvm on ]-inf+0i, 0+0i] * (warning: ln takes the other side of the cut values on ]-inf-0i, 0-0i]). */ - return Complex(std::log(c)); + return Complex::Builder(std::log(c)); } Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); @@ -44,15 +44,11 @@ private: class NaperianLogarithm final : public Expression { public: NaperianLogarithm(const NaperianLogarithmNode * n) : Expression(n) {} - static NaperianLogarithm Builder(Expression child) { return NaperianLogarithm(child); } + static NaperianLogarithm Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("ln", 1, &UntypedBuilder); Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); -private: - explicit NaperianLogarithm(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/nth_root.h b/poincare/include/poincare/nth_root.h index 2e68e7466..9612cf8a2 100644 --- a/poincare/include/poincare/nth_root.h +++ b/poincare/include/poincare/nth_root.h @@ -35,16 +35,11 @@ private: class NthRoot final : public Expression { public: NthRoot(const NthRootNode * n) : Expression(n) {} - static NthRoot Builder(Expression child0, Expression child1) { return NthRoot(child0, child1); } + static NthRoot Builder(Expression child0, Expression child1); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("root", 2, &UntypedBuilder); Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); -private: - NthRoot(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child0); - replaceChildAtIndexInPlace(1, child1); - } }; } diff --git a/poincare/include/poincare/nth_root_layout.h b/poincare/include/poincare/nth_root_layout.h index 5cb5d51e3..1b2e27fc9 100644 --- a/poincare/include/poincare/nth_root_layout.h +++ b/poincare/include/poincare/nth_root_layout.h @@ -14,9 +14,9 @@ public: constexpr static KDCoordinate k_leftRadixHeight = 8; constexpr static KDCoordinate k_leftRadixWidth = 5; - NthRootLayoutNode() : + NthRootLayoutNode(bool hasIndex) : LayoutNode(), - m_hasIndex(false) + m_hasIndex(hasIndex) {} // LayoutNode @@ -50,14 +50,6 @@ private: constexpr static KDCoordinate k_heightMargin = 2; constexpr static KDCoordinate k_widthMargin = 2; constexpr static KDCoordinate k_radixLineThickness = 1; - void setNumberOfChildren(int number) { - assert(number == 1 || number == 2); - if (number == 1) { - m_hasIndex = false; - } else { - m_hasIndex = true; - } - } KDSize adjustedIndexSize(); void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) override; LayoutNode * radicandLayout() { return childAtIndex(0); } @@ -67,17 +59,9 @@ private: class NthRootLayout final : public Layout { public: - static NthRootLayout Builder(Layout radicand) { return NthRootLayout(radicand); } - static NthRootLayout Builder(Layout radicand, Layout index) { - NthRootLayout n(radicand); - n.addChildAtIndexInPlace(index, 1, 1); - static_cast(n.node())->setNumberOfChildren(2); - return n; - } -private: - NthRootLayout(Layout radicand) : Layout(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, radicand); - } + NthRootLayout() = delete; + static NthRootLayout Builder(Layout child); + static NthRootLayout Builder(Layout radicand, Layout index); }; } diff --git a/poincare/include/poincare/opposite.h b/poincare/include/poincare/opposite.h index 23f1f19df..424486585 100644 --- a/poincare/include/poincare/opposite.h +++ b/poincare/include/poincare/opposite.h @@ -10,7 +10,7 @@ class Opposite; class OppositeNode /*final*/ : public ExpressionNode { public: - template static Complex compute(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Degree) { return Complex(-c); } + template static Complex compute(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Degree) { return Complex::Builder(-c); } // TreeNode @@ -47,16 +47,10 @@ public: class Opposite final : public Expression { public: Opposite(const OppositeNode * n) : Expression(n) {} - static Opposite Builder() { return Opposite(); } - static Opposite Builder(Expression child) { return Opposite(child); } + static Opposite Builder(); + static Opposite Builder(Expression child); Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); - -private: - Opposite() : Expression(TreePool::sharedPool()->createTreeNode()) {} - explicit Opposite(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/parenthesis.h b/poincare/include/poincare/parenthesis.h index d4b940bea..ba8b2197e 100644 --- a/poincare/include/poincare/parenthesis.h +++ b/poincare/include/poincare/parenthesis.h @@ -38,14 +38,9 @@ private: class Parenthesis final : public Expression { public: Parenthesis(const ParenthesisNode * n) : Expression(n) {} - static Parenthesis Builder(Expression child) { return Parenthesis(child); } + static Parenthesis Builder(Expression child); // Expression Expression shallowReduce(); - -private: - Parenthesis(Expression exp) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, exp); - } }; } diff --git a/poincare/include/poincare/permute_coefficient.h b/poincare/include/poincare/permute_coefficient.h index 4c241bcf5..45cd8f8ee 100644 --- a/poincare/include/poincare/permute_coefficient.h +++ b/poincare/include/poincare/permute_coefficient.h @@ -41,17 +41,13 @@ private: class PermuteCoefficient final : public Expression { public: PermuteCoefficient(const PermuteCoefficientNode * n) : Expression(n) {} - static PermuteCoefficient Builder(Expression child0, Expression child1) { return PermuteCoefficient(child0, child1); } + static PermuteCoefficient Builder(Expression child0, Expression child1); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("permute", 2, &UntypedBuilder); // Expression Expression shallowReduce(); -private: - PermuteCoefficient(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child0); - replaceChildAtIndexInPlace(1, child1); - } + constexpr static int k_maxNValue = 100; }; diff --git a/poincare/include/poincare/power.h b/poincare/include/poincare/power.h index 8ddc1d6b0..2c30a77ff 100644 --- a/poincare/include/poincare/power.h +++ b/poincare/include/poincare/power.h @@ -67,7 +67,7 @@ class Power final : public Expression { friend class Round; public: Power(const PowerNode * n) : Expression(n) {} - static Power Builder(Expression base, Expression exponent) { return Power(base, exponent); } + static Power Builder(Expression base, Expression exponent); Expression setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const; @@ -78,12 +78,6 @@ private: constexpr static int k_maxExactPowerMatrix = 100; constexpr static int k_maxNumberOfTermsInExpandedMultinome = 25; - // Constructors - Power(Expression base, Expression exponent) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, base); - replaceChildAtIndexInPlace(1, exponent); - } - // Simplification Expression denominator(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; diff --git a/poincare/include/poincare/prediction_interval.h b/poincare/include/poincare/prediction_interval.h index 8ff5633f0..f21dc03e8 100644 --- a/poincare/include/poincare/prediction_interval.h +++ b/poincare/include/poincare/prediction_interval.h @@ -37,17 +37,12 @@ private: class PredictionInterval final : public Expression { public: PredictionInterval(const PredictionIntervalNode * n) : Expression(n) {} - static PredictionInterval Builder(Expression child0, Expression child1) { return PredictionInterval(child0, child1); } + static PredictionInterval Builder(Expression child0, Expression child1); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("prediction95", 2, &UntypedBuilder); // Expression Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); -private: - PredictionInterval(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child0); - replaceChildAtIndexInPlace(1, child1); - } }; } diff --git a/poincare/include/poincare/product.h b/poincare/include/poincare/product.h index 02701a19d..e57525551 100644 --- a/poincare/include/poincare/product.h +++ b/poincare/include/poincare/product.h @@ -35,7 +35,7 @@ class Product final : public Expression { friend class ProductNode; public: Product(const ProductNode * n) : Expression(n) {} - static Product Builder(Expression child0, Symbol child1, Expression child2, Expression child3) { return Product(child0, child1, child2, child3); } + static Product Builder(Expression child0, Symbol child1, Expression child2, Expression child3); static Expression UntypedBuilder(Expression children) { if (children.childAtIndex(1).type() != ExpressionNode::Type::Symbol) { // Second parameter must be a Symbol. @@ -44,14 +44,6 @@ public: return Builder(children.childAtIndex(0), children.childAtIndex(1).convert(), children.childAtIndex(2), children.childAtIndex(3)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("product", 4, &UntypedBuilder); -private: - Product(Expression child0, Expression child1, Expression child2, Expression child3) : Expression(TreePool::sharedPool()->createTreeNode()) { - assert(child1.type() == ExpressionNode::Type::Symbol); - replaceChildAtIndexInPlace(0, child0); - replaceChildAtIndexInPlace(1, child1); - replaceChildAtIndexInPlace(2, child2); - replaceChildAtIndexInPlace(3, child3); - } }; } diff --git a/poincare/include/poincare/product_layout.h b/poincare/include/poincare/product_layout.h index 7c2298d95..eeb28ec79 100644 --- a/poincare/include/poincare/product_layout.h +++ b/poincare/include/poincare/product_layout.h @@ -25,16 +25,8 @@ private: class ProductLayout final : public Layout { public: - static ProductLayout Builder(Layout argument, Layout variable, Layout lowerB, Layout upperB) { return ProductLayout(argument, variable, lowerB, upperB); } -private: - ProductLayout(Layout argument, Layout variable, Layout lowerB, Layout upperB) : - Layout(TreePool::sharedPool()->createTreeNode()) - { - replaceChildAtIndexInPlace(0, argument); - replaceChildAtIndexInPlace(1, variable); - replaceChildAtIndexInPlace(2, lowerB); - replaceChildAtIndexInPlace(3, upperB); - } + static ProductLayout Builder(Layout argument, Layout variable, Layout lowerB, Layout upperB); + ProductLayout() = delete; }; } diff --git a/poincare/include/poincare/randint.h b/poincare/include/poincare/randint.h index 5f549a75d..469dc209a 100644 --- a/poincare/include/poincare/randint.h +++ b/poincare/include/poincare/randint.h @@ -41,14 +41,9 @@ class Randint final : public Expression { friend class RandintNode; public: Randint(const RandintNode * n) : Expression(n) {} - static Randint Builder(Expression child0, Expression child1) { return Randint(child0, child1); } + static Randint Builder(Expression child0, Expression child1); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("randint", 2, &UntypedBuilder); -private: - Randint(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child0); - replaceChildAtIndexInPlace(1, child1); - } }; } diff --git a/poincare/include/poincare/random.h b/poincare/include/poincare/random.h index 30cc8dbb9..8b74c5b56 100644 --- a/poincare/include/poincare/random.h +++ b/poincare/include/poincare/random.h @@ -43,13 +43,12 @@ class Random final : public Expression { friend class RandomNode; public: Random(const RandomNode * n) : Expression(n) {} - static Random Builder() { return Random(); } + static Random Builder(); static Expression UntypedBuilder(Expression children) { return Builder(); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("random", 0, &UntypedBuilder); template static T random(); private: - Random() : Expression(TreePool::sharedPool()->createTreeNode()) {} Expression setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); }; diff --git a/poincare/include/poincare/rational.h b/poincare/include/poincare/rational.h index d9c3c8612..03e241a28 100644 --- a/poincare/include/poincare/rational.h +++ b/poincare/include/poincare/rational.h @@ -9,11 +9,7 @@ namespace Poincare { class RationalNode final : public NumberNode { public: - RationalNode() : - m_negative(false), - m_numberOfDigitsNumerator(0), - m_numberOfDigitsDenominator(0) {} - virtual void setDigits(const native_uint_t * i, uint8_t numeratorSize, const native_uint_t * j, uint8_t denominatorSize, bool negative); + RationalNode(const native_uint_t * i, uint8_t numeratorSize, const native_uint_t * j, uint8_t denominatorSize, bool negative); Integer signedNumerator() const; Integer unsignedNumerator() const; @@ -22,7 +18,6 @@ public: void setNegative(bool negative) { m_negative = negative; } // TreeNode - void initToMatchSize(size_t goalSize) override; size_t size() const override; #if POINCARE_TREE_LOG virtual void logNodeName(std::ostream & stream) const override { @@ -42,8 +37,8 @@ public: Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; // Approximation - Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return Complex(templatedApproximate()); } - Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return Complex(templatedApproximate()); } + Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return Complex::Builder(templatedApproximate()); } + Evaluation approximate(DoublePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return Complex::Builder(templatedApproximate()); } template T templatedApproximate() const; // Basic test @@ -74,11 +69,11 @@ class Rational final : public Number { public: /* The constructor build a irreductible fraction */ Rational(const RationalNode * node) : Number(node) {} - Rational(Integer & num, Integer & den); - Rational(const Integer & numerator); - Rational(native_int_t i); - Rational(native_int_t i, native_int_t j); - Rational(const char * iString, const char * jString); + static Rational Builder(Integer & num, Integer & den); + static Rational Builder(const Integer & numerator); + static Rational Builder(native_int_t i); + static Rational Builder(native_int_t i, native_int_t j); + static Rational Builder(const char * iString, const char * jString); // TreeNode RationalNode * node() const { return static_cast(Number::node()); } @@ -111,7 +106,8 @@ public: Expression shallowReduce(); private: - Rational(const native_uint_t * i, uint8_t numeratorSize, const native_uint_t * j, uint8_t denominatorSize, bool negative); + static Rational Builder(const native_uint_t * i, uint8_t numeratorSize, const native_uint_t * j, uint8_t denominatorSize, bool negative); + RationalNode * node() { return static_cast(Number::node()); } /* Simplification */ diff --git a/poincare/include/poincare/real_part.h b/poincare/include/poincare/real_part.h index e9107a486..ad7fba108 100644 --- a/poincare/include/poincare/real_part.h +++ b/poincare/include/poincare/real_part.h @@ -32,7 +32,7 @@ private: Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) override; // Evaluation template static Complex computeOnComplex(const std::complex c, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { - return Complex(std::real(c)); + return Complex::Builder(std::real(c)); } Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::Map(this, context, complexFormat, angleUnit,computeOnComplex); @@ -45,15 +45,11 @@ private: class RealPart final : public Expression { public: RealPart(const RealPartNode * n) : Expression(n) {} - static RealPart Builder(Expression child) { return RealPart(child); } + static RealPart Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("re", 1, &UntypedBuilder); Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); -private: - explicit RealPart(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/right_parenthesis_layout.h b/poincare/include/poincare/right_parenthesis_layout.h index 342634b7f..779039803 100644 --- a/poincare/include/poincare/right_parenthesis_layout.h +++ b/poincare/include/poincare/right_parenthesis_layout.h @@ -36,9 +36,8 @@ protected: class RightParenthesisLayout final : public Layout { public: - static RightParenthesisLayout Builder() { return RightParenthesisLayout(); } -private: - RightParenthesisLayout() : Layout(TreePool::sharedPool()->createTreeNode()) {} + static RightParenthesisLayout Builder(); + RightParenthesisLayout() = delete; }; } diff --git a/poincare/include/poincare/right_square_bracket_layout.h b/poincare/include/poincare/right_square_bracket_layout.h index 860c15e20..8c7ff1332 100644 --- a/poincare/include/poincare/right_square_bracket_layout.h +++ b/poincare/include/poincare/right_square_bracket_layout.h @@ -29,10 +29,8 @@ protected: class RightSquareBracketLayout final : public Layout { public: - static RightSquareBracketLayout Builder() { return RightSquareBracketLayout(); } - -private: - RightSquareBracketLayout() : Layout(TreePool::sharedPool()->createTreeNode()) {} + static RightSquareBracketLayout Builder(); + RightSquareBracketLayout() = delete; }; } diff --git a/poincare/include/poincare/round.h b/poincare/include/poincare/round.h index a219cc775..d397217cc 100644 --- a/poincare/include/poincare/round.h +++ b/poincare/include/poincare/round.h @@ -38,16 +38,11 @@ private: class Round final : public Expression { public: Round(const RoundNode * n) : Expression(n) {} - static Round Builder(Expression child0, Expression child1) { return Round(child0, child1); } + static Round Builder(Expression child0, Expression child1); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("round", 2, &UntypedBuilder); Expression shallowReduce(); -private: - Round(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child0); - replaceChildAtIndexInPlace(1, child1); - } }; } diff --git a/poincare/include/poincare/sign_function.h b/poincare/include/poincare/sign_function.h index 9bb83d47e..3205d8d7b 100644 --- a/poincare/include/poincare/sign_function.h +++ b/poincare/include/poincare/sign_function.h @@ -45,15 +45,11 @@ private: class SignFunction final : public Expression { public: SignFunction(const SignFunctionNode * n) : Expression(n) {} - static SignFunction Builder(Expression child) { return SignFunction(child); } + static SignFunction Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("sign", 1, &UntypedBuilder); Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); -private: - explicit SignFunction(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/sine.h b/poincare/include/poincare/sine.h index 393ae365c..f53614b9e 100644 --- a/poincare/include/poincare/sine.h +++ b/poincare/include/poincare/sine.h @@ -48,15 +48,11 @@ private: class Sine final : public Expression { public: Sine(const SineNode * n) : Expression(n) {} - static Sine Builder(Expression child) { return Sine(child); } + static Sine Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("sin", 1, &UntypedBuilder); Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); -private: - explicit Sine(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/square_root.h b/poincare/include/poincare/square_root.h index 4a1401c69..a47c17adb 100644 --- a/poincare/include/poincare/square_root.h +++ b/poincare/include/poincare/square_root.h @@ -41,16 +41,13 @@ private: class SquareRoot final : public Expression { public: SquareRoot(const SquareRootNode * n) : Expression(n) {} - static SquareRoot Builder(Expression child) { return SquareRoot(child); } + static SquareRoot Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static_assert('\x91' == Ion::Charset::Root, "Charset error"); static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("\x91", 1, &UntypedBuilder); Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); private: - explicit SquareRoot(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } static const char k_name[2]; }; diff --git a/poincare/include/poincare/store.h b/poincare/include/poincare/store.h index 0d780cd75..e9db5570b 100644 --- a/poincare/include/poincare/store.h +++ b/poincare/include/poincare/store.h @@ -40,7 +40,7 @@ class Store final : public Expression { friend class StoreNode; public: Store(const StoreNode * n) : Expression(n) {} - static Store Builder(Expression value, SymbolAbstract symbol) { return Store(value, symbol); } + static Store Builder(Expression value, SymbolAbstract symbol); // Store const SymbolAbstract symbol() const { @@ -54,12 +54,8 @@ public: // Expression Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); -private: - Store(Expression value, SymbolAbstract symbol) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, value); - replaceChildAtIndexInPlace(1, symbol); - } +private: Expression storeValueForSymbol(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; StoreNode * node() const { return static_cast(Expression::node()); } }; diff --git a/poincare/include/poincare/subtraction.h b/poincare/include/poincare/subtraction.h index faae9c66b..3fd149bcc 100644 --- a/poincare/include/poincare/subtraction.h +++ b/poincare/include/poincare/subtraction.h @@ -25,7 +25,7 @@ public: int polynomialDegree(Context & context, const char * symbolName) const override; // Approximation - template static Complex compute(const std::complex c, const std::complex d, Preferences::ComplexFormat complexFormat) { return Complex(c - d); } + template static Complex compute(const std::complex c, const std::complex d, Preferences::ComplexFormat complexFormat) { return Complex::Builder(c - d); } Evaluation approximate(SinglePrecision p, Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return ApproximationHelper::MapReduce(this, context, complexFormat, angleUnit, compute, computeOnComplexAndMatrix, computeOnMatrixAndComplex, computeOnMatrices); } @@ -55,19 +55,12 @@ private: class Subtraction final : public Expression { public: Subtraction(const SubtractionNode * n) : Expression(n) {} - static Subtraction Builder() { return Subtraction(); } - static Subtraction Builder(Expression child0, Expression child1) { - Subtraction s = Subtraction::Builder(); - s.replaceChildAtIndexInPlace(0, child0); - s.replaceChildAtIndexInPlace(1, child1); - return s; - } + static Subtraction Builder(); + static Subtraction Builder(Expression child0, Expression child1); // Expression Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); -private: - Subtraction() : Expression(TreePool::sharedPool()->createTreeNode()) {} }; } diff --git a/poincare/include/poincare/sum.h b/poincare/include/poincare/sum.h index 515290d56..0d9cc6da2 100644 --- a/poincare/include/poincare/sum.h +++ b/poincare/include/poincare/sum.h @@ -35,7 +35,7 @@ class Sum final : public Expression { friend class SumNode; public: Sum(const SumNode * n) : Expression(n) {} - static Sum Builder(Expression child0, Symbol child1, Expression child2, Expression child3) { return Sum(child0, child1, child2, child3); } + static Sum Builder(Expression child0, Symbol child1, Expression child2, Expression child3); static Expression UntypedBuilder(Expression children) { if (children.childAtIndex(1).type() != ExpressionNode::Type::Symbol) { // Second parameter must be a Symbol. @@ -44,14 +44,6 @@ public: return Builder(children.childAtIndex(0), children.childAtIndex(1).convert(), children.childAtIndex(2), children.childAtIndex(3)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("sum", 4, &UntypedBuilder); -private: - Sum(Expression child0, Expression child1, Expression child2, Expression child3) : Expression(TreePool::sharedPool()->createTreeNode()) { - assert(child1.type() == ExpressionNode::Type::Symbol); - replaceChildAtIndexInPlace(0, child0); - replaceChildAtIndexInPlace(1, child1); - replaceChildAtIndexInPlace(2, child2); - replaceChildAtIndexInPlace(3, child3); - } }; } diff --git a/poincare/include/poincare/sum_layout.h b/poincare/include/poincare/sum_layout.h index a21b6fd38..b7999571e 100644 --- a/poincare/include/poincare/sum_layout.h +++ b/poincare/include/poincare/sum_layout.h @@ -23,16 +23,8 @@ private: class SumLayout final : public Layout { public: - static SumLayout Builder(Layout argument, Layout variable, Layout lowerB, Layout upperB) { return SumLayout(argument, variable, lowerB, upperB); } -private: - SumLayout(Layout argument, Layout variable, Layout lowerB, Layout upperB) : - Layout(TreePool::sharedPool()->createTreeNode()) - { - replaceChildAtIndexInPlace(0, argument); - replaceChildAtIndexInPlace(1, variable); - replaceChildAtIndexInPlace(2, lowerB); - replaceChildAtIndexInPlace(3, upperB); - } + static SumLayout Builder(Layout argument, Layout variable, Layout lowerB, Layout upperB); + SumLayout() = delete; }; } diff --git a/poincare/include/poincare/symbol.h b/poincare/include/poincare/symbol.h index e1fc8bf19..776498cac 100644 --- a/poincare/include/poincare/symbol.h +++ b/poincare/include/poincare/symbol.h @@ -7,6 +7,8 @@ namespace Poincare { class SymbolNode final : public SymbolAbstractNode { public: + SymbolNode(const char * newName, int length); + const char * name() const override { return m_name; } // TreeNode @@ -61,13 +63,13 @@ public: * characters but events as 'end of text', 'backspace'... */ UnknownX = 1, }; - Symbol(const char * name, int length); - Symbol(char name); Symbol(const SymbolNode * node) : SymbolAbstract(node) {} - static Symbol Ans() { return Symbol(k_ans, k_ansLength); } + static Symbol Builder(const char * name, int length); + static Symbol Builder(char name); + static Symbol Ans() { return Symbol::Builder(k_ans, k_ansLength); } static Expression UntypedBuilder(const char * name, size_t length, Context * context) { // create an expression only if it is not in the context or defined as a symbol - Symbol s(name, length); + Symbol s = Symbol::Builder(name, length); if (SymbolAbstract::ValidInContext(s, context)) { return s; } diff --git a/poincare/include/poincare/symbol_abstract.h b/poincare/include/poincare/symbol_abstract.h index 3de47c6c5..c993ef2ad 100644 --- a/poincare/include/poincare/symbol_abstract.h +++ b/poincare/include/poincare/symbol_abstract.h @@ -27,9 +27,7 @@ class SymbolAbstractNode : public ExpressionNode { friend class Store; public: virtual const char * name() const = 0; - void setName(const char * newName, int length); size_t size() const override; - void initToMatchSize(size_t goalSize) override; // ExpressionNode int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const override; diff --git a/poincare/include/poincare/tangent.h b/poincare/include/poincare/tangent.h index dc271379a..b37a99d35 100644 --- a/poincare/include/poincare/tangent.h +++ b/poincare/include/poincare/tangent.h @@ -46,15 +46,11 @@ private: class Tangent final : public Expression { public: Tangent(const TangentNode * n) : Expression(n) {} - static Tangent Builder(Expression child) { return Tangent(child); } + static Tangent Builder(Expression child); static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("tan", 1, &UntypedBuilder); Expression shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target); -private: - explicit Tangent(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child); - } }; } diff --git a/poincare/include/poincare/tree_handle.h b/poincare/include/poincare/tree_handle.h index 87b6ade6d..abd3008d6 100644 --- a/poincare/include/poincare/tree_handle.h +++ b/poincare/include/poincare/tree_handle.h @@ -104,6 +104,9 @@ protected: /* Constructor */ TreeHandle(const TreeNode * node); TreeHandle(int nodeIndentifier = TreeNode::NoNodeIdentifier) : m_identifier(nodeIndentifier) {} + // WARNING: if the children table is the result of a cast, the object downcasted has to be the same size as a TreeHandle. + static TreeHandle BuildWithBasicChildren(TreeNode * node, TreeHandle * children = nullptr, int numberOfChildren = 0); + void setIdentifierAndRetain(int newId); void setTo(const TreeHandle & tr); diff --git a/poincare/include/poincare/tree_node.h b/poincare/include/poincare/tree_node.h index 4a5393b4f..26b9efb57 100644 --- a/poincare/include/poincare/tree_node.h +++ b/poincare/include/poincare/tree_node.h @@ -42,7 +42,6 @@ public: static constexpr int NoNodeIdentifier = -1; // Constructor and destructor - virtual void initToMatchSize(size_t goalSize) { assert(false); } virtual ~TreeNode() {} // Attributes diff --git a/poincare/include/poincare/tree_pool.h b/poincare/include/poincare/tree_pool.h index 3399f2f18..78c8a7342 100644 --- a/poincare/include/poincare/tree_pool.h +++ b/poincare/include/poincare/tree_pool.h @@ -31,8 +31,8 @@ public: return m_nodeForIdentifier[identifier]; } - template - T * createTreeNode(size_t size = sizeof(T)); + // Pool memory + void * alloc(size_t size); void move(TreeNode * destination, TreeNode * source, int realNumberOfSourceChildren); void moveChildren(TreeNode * destination, TreeNode * sourceParent); void removeChildren(TreeNode * node, int nodeNumberOfChildren); @@ -54,7 +54,6 @@ private: static TreePool * SharedStaticPool; // TreeNode - void addGhostChildrenAndRename(TreeNode * node); void discardTreeNode(TreeNode * node); void registerNode(TreeNode * node); void unregisterNode(TreeNode * node) { @@ -106,7 +105,6 @@ private: RootNodes roots() { return RootNodes(first()); } // Pool memory - void * alloc(size_t size); void dealloc(TreeNode * ptr, size_t size); void moveNodes(TreeNode * destination, TreeNode * source, size_t moveLength); diff --git a/poincare/include/poincare/undefined.h b/poincare/include/poincare/undefined.h index 1d76553bb..8891fe236 100644 --- a/poincare/include/poincare/undefined.h +++ b/poincare/include/poincare/undefined.h @@ -41,8 +41,8 @@ protected: class Undefined final : public Number { public: - Undefined() : Number(TreePool::sharedPool()->createTreeNode()) {} Undefined(const UndefinedNode * n) : Number(n) {} + static Undefined Builder(); static const char * Name() { return "undef"; } diff --git a/poincare/include/poincare/unreal.h b/poincare/include/poincare/unreal.h index 23e0f78b2..232f3607d 100644 --- a/poincare/include/poincare/unreal.h +++ b/poincare/include/poincare/unreal.h @@ -39,7 +39,8 @@ private: class Unreal final : public Number { public: - Unreal() : Number(TreePool::sharedPool()->createTreeNode()) {} + static Unreal Builder(); + Unreal() = delete; static const char * Name() { return "unreal"; } diff --git a/poincare/include/poincare/vertical_offset_layout.h b/poincare/include/poincare/vertical_offset_layout.h index 8ac17b24f..94162aa44 100644 --- a/poincare/include/poincare/vertical_offset_layout.h +++ b/poincare/include/poincare/vertical_offset_layout.h @@ -20,7 +20,6 @@ public: // VerticalOffsetLayoutNode Type type() const { return m_type; } - void setType(Type type) { m_type = type; } // LayoutNode void moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout) override; @@ -59,15 +58,8 @@ private: class VerticalOffsetLayout final : public Layout { public: - static VerticalOffsetLayout Builder(Layout l, VerticalOffsetLayoutNode::Type type) { return VerticalOffsetLayout(l, type); } - -private: - VerticalOffsetLayout(Layout l, VerticalOffsetLayoutNode::Type type) : - Layout(TreePool::sharedPool()->createTreeNode()) - { - static_cast(node())->setType(type); - replaceChildAtIndexInPlace(0,l); - } + static VerticalOffsetLayout Builder(Layout l, VerticalOffsetLayoutNode::Type type); + VerticalOffsetLayout() = delete; }; } diff --git a/poincare/src/absolute_value.cpp b/poincare/src/absolute_value.cpp index a057ae5f0..2999aef0f 100644 --- a/poincare/src/absolute_value.cpp +++ b/poincare/src/absolute_value.cpp @@ -31,6 +31,13 @@ Expression AbsoluteValueNode::shallowReduce(Context & context, Preferences::Comp return AbsoluteValue(this).shallowReduce(context, complexFormat, angleUnit, target); } +AbsoluteValue AbsoluteValue::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(AbsoluteValueNode)); + AbsoluteValueNode * node = new (bufferNode) AbsoluteValueNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + Expression AbsoluteValue::setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { assert(s == ExpressionNode::Sign::Positive); return *this; @@ -62,7 +69,7 @@ Expression AbsoluteValue::shallowReduce(Context & context, Preferences::ComplexF } else if (!std::isnan(app) && ((c.isNumber() && app < 0.0f) || app <= -Expression::Epsilon())) { // abs(a) = -a with a < 0 (same comment as above to check that a < 0) - Multiplication m = Multiplication::Builder(Rational(-1), c); + Multiplication m = Multiplication::Builder(Rational::Builder(-1), c); replaceWithInPlace(m); return m.shallowReduce(context, complexFormat, angleUnit, target); } diff --git a/poincare/src/absolute_value_layout.cpp b/poincare/src/absolute_value_layout.cpp new file mode 100644 index 000000000..0d445c654 --- /dev/null +++ b/poincare/src/absolute_value_layout.cpp @@ -0,0 +1,12 @@ +#include + +namespace Poincare { + +AbsoluteValueLayout AbsoluteValueLayout::Builder(Layout child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(AbsoluteValueLayoutNode)); + AbsoluteValueLayoutNode * node = new (bufferNode) AbsoluteValueLayoutNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + +} diff --git a/poincare/src/addition.cpp b/poincare/src/addition.cpp index 73814db1e..80361ed50 100644 --- a/poincare/src/addition.cpp +++ b/poincare/src/addition.cpp @@ -65,7 +65,7 @@ const Number Addition::NumeralFactor(const Expression & e) { Number result = e.childAtIndex(0).convert(); return result; } - return Rational(1); + return Rational::Builder(1); } int Addition::getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const { @@ -74,7 +74,7 @@ int Addition::getPolynomialCoefficients(Context & context, const char * symbolNa return -1; } for (int k = 0; k < deg+1; k++) { - coefficients[k] = Addition(); + coefficients[k] = Addition::Builder(); } Expression intermediateCoefficients[Expression::k_maxNumberOfPolynomialCoefficients]; for (int i = 0; i < numberOfChildren(); i++) { @@ -87,6 +87,21 @@ int Addition::getPolynomialCoefficients(Context & context, const char * symbolNa return deg; } +Addition Addition::Builder() { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(AdditionNode)); + AdditionNode * node = new (bufferNode) AdditionNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); +} + +Addition Addition::Builder(Expression * children, size_t numberOfChildren) { + Addition a = Addition::Builder(); + for (int i = 0; i < numberOfChildren; i++) { + a.addChildAtIndexInPlace(children[i], i, i); + } + return a; +} + Expression Addition::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { /* Beautifying AdditionNode essentially consists in adding Subtractions if * needed. @@ -182,7 +197,7 @@ Expression Addition::shallowReduce(Context & context, Preferences::ComplexFormat int on = currentMatrix->numberOfRows(); int om = currentMatrix->numberOfColumns(); if (on != n || om != m) { - return replaceWith(new Undefined(), true); + return replaceWith(new Undefined::Builder(), true); } // Dispatch the current matrix children in the created additions matrix for (int j = 0; j < n*m; j++) { @@ -340,7 +355,7 @@ Expression Addition::factorizeOnCommonDenominator(Context & context, Preferences // We want to turn (a/b+c/d+e/b) into (a*d+b*c+e*d)/(b*d) // Step 1: We want to compute the common denominator, b*d - Multiplication commonDenominator; + Multiplication commonDenominator = Multiplication::Builder(); for (int i = 0; i < numberOfChildren(); i++) { Expression currentDenominator = childAtIndex(i).denominator(context, complexFormat, angleUnit); if (!currentDenominator.isUninitialized()) { @@ -363,7 +378,7 @@ Expression Addition::factorizeOnCommonDenominator(Context & context, Preferences } // Step 3: Add the denominator - Power inverseDenominator = Power::Builder(commonDenominator, Rational(-1)); + Power inverseDenominator = Power::Builder(commonDenominator, Rational::Builder(-1)); Multiplication result = Multiplication::Builder(numerator, inverseDenominator); // Step 4: Simplify the numerator diff --git a/poincare/src/approximation_helper.cpp b/poincare/src/approximation_helper.cpp index e77e39c27..bb4935d00 100644 --- a/poincare/src/approximation_helper.cpp +++ b/poincare/src/approximation_helper.cpp @@ -34,7 +34,7 @@ template Evaluation ApproximationHelper::Map(const ExpressionNode } else { assert(input.type() == EvaluationNode::Type::MatrixComplex); MatrixComplex m = static_cast &>(input); - MatrixComplex result; + MatrixComplex result = MatrixComplex::Builder(); for (int i = 0; i < m.numberOfChildren(); i++) { result.addChildAtIndexInPlace(compute(m.complexAtIndex(i), complexFormat, angleUnit), i, i); } @@ -71,7 +71,7 @@ template Evaluation ApproximationHelper::MapReduce(const Expressi } template MatrixComplex ApproximationHelper::ElementWiseOnMatrixComplexAndComplex(const MatrixComplex m, const std::complex c, Poincare::Preferences::ComplexFormat complexFormat, ComplexAndComplexReduction computeOnComplexes) { - MatrixComplex matrix; + MatrixComplex matrix = MatrixComplex::Builder(); for (int i = 0; i < m.numberOfChildren(); i++) { matrix.addChildAtIndexInPlace(computeOnComplexes(m.complexAtIndex(i), c, complexFormat), i, i); } @@ -83,7 +83,7 @@ template MatrixComplex ApproximationHelper::ElementWiseOnComplexM if (m.numberOfRows() != n.numberOfRows() || m.numberOfColumns() != n.numberOfColumns()) { return MatrixComplex::Undefined(); } - MatrixComplex matrix; + MatrixComplex matrix = MatrixComplex::Builder(); for (int i = 0; i < m.numberOfChildren(); i++) { matrix.addChildAtIndexInPlace(computeOnComplexes(m.complexAtIndex(i), n.complexAtIndex(i), complexFormat), i, i); } diff --git a/poincare/src/arc_cosine.cpp b/poincare/src/arc_cosine.cpp index 100e52963..f32d5f6c5 100644 --- a/poincare/src/arc_cosine.cpp +++ b/poincare/src/arc_cosine.cpp @@ -45,7 +45,14 @@ Complex ArcCosineNode::computeOnComplex(const std::complex c, Preferences: } } result = Trigonometry::RoundToMeaningfulDigits(result, c); - return Complex(Trigonometry::ConvertRadianToAngleUnit(result, angleUnit)); + return Complex::Builder(Trigonometry::ConvertRadianToAngleUnit(result, angleUnit)); +} + +ArcCosine ArcCosine::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(ArcCosineNode)); + ArcCosineNode * node = new (bufferNode) ArcCosineNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); } Expression ArcCosine::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { diff --git a/poincare/src/arc_sine.cpp b/poincare/src/arc_sine.cpp index 4493f0e2b..450c8df5f 100644 --- a/poincare/src/arc_sine.cpp +++ b/poincare/src/arc_sine.cpp @@ -45,7 +45,14 @@ Complex ArcSineNode::computeOnComplex(const std::complex c, Preferences::C } } result = Trigonometry::RoundToMeaningfulDigits(result, c); - return Complex(Trigonometry::ConvertRadianToAngleUnit(result, angleUnit)); + return Complex::Builder(Trigonometry::ConvertRadianToAngleUnit(result, angleUnit)); +} + +ArcSine ArcSine::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(ArcSineNode)); + ArcSineNode * node = new (bufferNode) ArcSineNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); } Expression ArcSine::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { diff --git a/poincare/src/arc_tangent.cpp b/poincare/src/arc_tangent.cpp index 917b2bc55..71fae7d4c 100644 --- a/poincare/src/arc_tangent.cpp +++ b/poincare/src/arc_tangent.cpp @@ -41,13 +41,20 @@ Complex ArcTangentNode::computeOnComplex(const std::complex c, Preferences } } result = Trigonometry::RoundToMeaningfulDigits(result, c); - return Complex(Trigonometry::ConvertRadianToAngleUnit(result, angleUnit)); + return Complex::Builder(Trigonometry::ConvertRadianToAngleUnit(result, angleUnit)); } Expression ArcTangentNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { return ArcTangent(this).shallowReduce(context, complexFormat, angleUnit, target); } +ArcTangent ArcTangent::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(ArcTangentNode)); + ArcTangentNode * node = new (bufferNode) ArcTangentNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + Expression ArcTangent::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { { Expression e = Expression::defaultShallowReduce(); diff --git a/poincare/src/binomial_coefficient.cpp b/poincare/src/binomial_coefficient.cpp index 72661df33..5a039966d 100644 --- a/poincare/src/binomial_coefficient.cpp +++ b/poincare/src/binomial_coefficient.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -34,7 +35,7 @@ Complex BinomialCoefficientNode::templatedApproximate(Context& context, Prefe Evaluation kInput = childAtIndex(1)->approximate(T(), context, complexFormat, angleUnit); T n = nInput.toScalar(); T k = kInput.toScalar(); - return Complex(compute(k, n)); + return Complex::Builder(compute(k, n)); } template @@ -53,6 +54,13 @@ T BinomialCoefficientNode::compute(T k, T n) { return std::round(result); } +BinomialCoefficient BinomialCoefficient::Builder(Expression child0, Expression child1) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(BinomialCoefficientNode)); + BinomialCoefficientNode * node = new (bufferNode) BinomialCoefficientNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(child0, child1).array(), 2); + return static_cast(h); +} + Expression BinomialCoefficient::shallowReduce() { { Expression e = Expression::defaultShallowReduce(); @@ -64,13 +72,13 @@ Expression BinomialCoefficient::shallowReduce() { Expression c1 = childAtIndex(1); #if MATRIX_EXACT_REDUCING if (c0.type() == ExpressionNode::Type::Matrix || c1.type() == ExpressionNode::Type::Matrix) { - return Undefined(); + return Undefined::Builder(); } #endif if (c0.type() == ExpressionNode::Type::Rational) { Rational r0 = static_cast(c0); if (!r0.integerDenominator().isOne() || r0.isNegative()) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -78,7 +86,7 @@ Expression BinomialCoefficient::shallowReduce() { if (c1.type() == ExpressionNode::Type::Rational) { Rational r1 = static_cast(c1); if (!r1.integerDenominator().isOne() || r1.isNegative()) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -92,7 +100,7 @@ Expression BinomialCoefficient::shallowReduce() { Integer n = r0.signedIntegerNumerator(); Integer k = r1.signedIntegerNumerator(); if (n.isLowerThan(k)) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -101,21 +109,20 @@ Expression BinomialCoefficient::shallowReduce() { if (Integer(k_maxNValue).isLowerThan(n)) { return *this; } - Rational result(1); + Rational result = Rational::Builder(1); Integer kBis = Integer::Subtraction(n, k); k = kBis.isLowerThan(k) ? kBis : k; int clippedK = k.extractedInt(); // Authorized because k < n < k_maxNValue for (int i = 0; i < clippedK; i++) { Integer nMinusI = Integer::Subtraction(n, Integer(i)); Integer kMinusI = Integer::Subtraction(k, Integer(i)); - Rational factor = Rational(nMinusI, kMinusI); + Rational factor = Rational::Builder(nMinusI, kMinusI); result = Rational::Multiplication(result, factor); } // As we cap the n < k_maxNValue = 300, result < binomial(300, 150) ~2^89 assert(!result.numeratorOrDenominatorIsInfinity()); - Expression rationalResult = Rational(result); - replaceWithInPlace(rationalResult); - return rationalResult; + replaceWithInPlace(result); + return result; } template double BinomialCoefficientNode::compute(double k, double n); diff --git a/poincare/src/binomial_coefficient_layout.cpp b/poincare/src/binomial_coefficient_layout.cpp index 97872cc55..dc7b95788 100644 --- a/poincare/src/binomial_coefficient_layout.cpp +++ b/poincare/src/binomial_coefficient_layout.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -106,4 +107,11 @@ void BinomialCoefficientLayoutNode::render(KDContext * ctx, KDPoint p, KDColor e RightParenthesisLayoutNode::RenderWithChildHeight(childHeight, ctx, p.translatedBy(KDPoint(rightParenthesisPointX, 0)), expressionColor, backgroundColor); } +BinomialCoefficientLayout BinomialCoefficientLayout::Builder(Layout n, Layout k) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(BinomialCoefficientLayoutNode)); + BinomialCoefficientLayoutNode * node = new (bufferNode) BinomialCoefficientLayoutNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(n,k).array(), 2); + return static_cast(h); +} + } diff --git a/poincare/src/ceiling.cpp b/poincare/src/ceiling.cpp index cd8ddf05c..9742abffe 100644 --- a/poincare/src/ceiling.cpp +++ b/poincare/src/ceiling.cpp @@ -28,13 +28,20 @@ Complex CeilingNode::computeOnComplex(const std::complex c, Preferences::C if (c.imag() != 0) { return Complex::Undefined(); } - return Complex(std::ceil(c.real())); + return Complex::Builder(std::ceil(c.real())); } Expression CeilingNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { return Ceiling(this).shallowReduce(); } +Ceiling Ceiling::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(CeilingNode)); + CeilingNode * node = new (bufferNode) CeilingNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + Expression Ceiling::shallowReduce() { { Expression e = Expression::defaultShallowReduce(); @@ -52,10 +59,10 @@ Expression Ceiling::shallowReduce() { Constant s = static_cast(c); Expression result; if (s.isPi()) { - result = Rational(4); + result = Rational::Builder(4); } if (s.isExponential()) { - result = Rational(3); + result = Rational::Builder(3); } if (!result.isUninitialized()) { replaceWithInPlace(result); @@ -70,7 +77,7 @@ Expression Ceiling::shallowReduce() { IntegerDivision div = Integer::Division(r.signedIntegerNumerator(), r.integerDenominator()); assert(!div.remainder.isOverflow()); if (div.remainder.isZero()) { - Expression result = Rational(div.quotient); + Expression result = Rational::Builder(div.quotient); replaceWithInPlace(result); return result; } @@ -78,7 +85,7 @@ Expression Ceiling::shallowReduce() { if (result.isOverflow()) { return *this; } - Expression rationalResult = Rational(result); + Expression rationalResult = Rational::Builder(result); replaceWithInPlace(rationalResult); return rationalResult; } diff --git a/poincare/src/ceiling_layout.cpp b/poincare/src/ceiling_layout.cpp index 3a7c5aff3..0c2c679f7 100644 --- a/poincare/src/ceiling_layout.cpp +++ b/poincare/src/ceiling_layout.cpp @@ -2,4 +2,11 @@ namespace Poincare { +CeilingLayout CeilingLayout::Builder(Layout child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(CeilingLayoutNode)); + CeilingLayoutNode * node = new (bufferNode) CeilingLayoutNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + } diff --git a/poincare/src/char_layout.cpp b/poincare/src/char_layout.cpp index b49a0d0b9..d303a5b89 100644 --- a/poincare/src/char_layout.cpp +++ b/poincare/src/char_layout.cpp @@ -96,11 +96,11 @@ bool CharLayoutNode::isMultiplicationChar() const { || m_char == Ion::Charset::MiddleDot; } -CharLayout::CharLayout(char c, const KDFont * font) : - Layout(TreePool::sharedPool()->createTreeNode()) -{ - node()->setChar(c); - node()->setFont(font); +CharLayout CharLayout::Builder(char c, const KDFont * font) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(CharLayoutNode)); + CharLayoutNode * node = new (bufferNode) CharLayoutNode(c, font); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); } } diff --git a/poincare/src/complex.cpp b/poincare/src/complex.cpp index 5935fddce..7ea64fee8 100644 --- a/poincare/src/complex.cpp +++ b/poincare/src/complex.cpp @@ -22,12 +22,13 @@ extern "C" { namespace Poincare { template -void ComplexNode::setComplex(std::complex c) { +ComplexNode::ComplexNode(std::complex c) : + EvaluationNode(), + std::complex(c.real(), c.imag()) +{ if (!std::isnan(c.imag()) && c.imag() != 0.0) { Expression::SetEncounteredComplex(true); } - this->real(c.real()); - this->imag(c.imag()); if (this->real() == -0) { this->real(0); } @@ -47,7 +48,7 @@ T ComplexNode::toScalar() const { template Expression ComplexNode::complexToExpression(Preferences::ComplexFormat complexFormat) const { if (complexFormat == Preferences::ComplexFormat::Real && Expression::EncounteredComplex()) { - return Unreal(); + return Unreal::Builder(); } T ra, tb; if (complexFormat == Preferences::ComplexFormat::Polar) { @@ -67,17 +68,18 @@ Expression ComplexNode::complexToExpression(Preferences::ComplexFormat comple } template -Complex::Complex(std::complex c) : - Evaluation(TreePool::sharedPool()->createTreeNode>()) -{ - node()->setComplex(c); +Complex Complex::Builder(std::complex c) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(ComplexNode)); + ComplexNode * node = new (bufferNode) ComplexNode(c); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast &>(h); } template class ComplexNode; template class ComplexNode; -template Complex::Complex(float a, float b); -template Complex::Complex(double a, double b); -template Complex::Complex(std::complex c); -template Complex::Complex(std::complex c); +template Complex Complex::Builder(float a, float b); +template Complex Complex::Builder(double a, double b); +template Complex Complex::Builder(std::complex c); +template Complex Complex::Builder(std::complex c); } diff --git a/poincare/src/complex_argument.cpp b/poincare/src/complex_argument.cpp index 679ec064b..9ac1de038 100644 --- a/poincare/src/complex_argument.cpp +++ b/poincare/src/complex_argument.cpp @@ -30,7 +30,14 @@ Expression ComplexArgumentNode::shallowReduce(Context & context, Preferences::Co template Complex ComplexArgumentNode::computeOnComplex(const std::complex c, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) { - return Complex(std::arg(c)); + return Complex::Builder(std::arg(c)); +} + +ComplexArgument ComplexArgument::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(ComplexArgumentNode)); + ComplexArgumentNode * node = new (bufferNode) ComplexArgumentNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); } Expression ComplexArgument::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { @@ -51,18 +58,18 @@ Expression ComplexArgument::shallowReduce(Context & context, Preferences::Comple float app = c.node()->approximate(float(), context, complexFormat, angleUnit).toScalar(); if (!std::isnan(app) && app >= Expression::Epsilon()) { // arg(x) = 0 if x > 0 - Expression result = Rational(0); + Expression result = Rational::Builder(0); replaceWithInPlace(result); return result; } else if (!std::isnan(app) && app <= -Expression::Epsilon()) { // arg(x) = Pi if x < 0 - Expression result = Constant(Ion::Charset::SmallPi); + Expression result = Constant::Builder(Ion::Charset::SmallPi); replaceWithInPlace(result); return result; } } if (real || c.type() == ExpressionNode::Type::ComplexCartesian) { - ComplexCartesian complexChild = real ? ComplexCartesian::Builder(c, Rational(0)) : static_cast(c); + ComplexCartesian complexChild = real ? ComplexCartesian::Builder(c, Rational::Builder(0)) : static_cast(c); Expression childArg = complexChild.argument(context, complexFormat, angleUnit, target); replaceWithInPlace(childArg); return childArg.shallowReduce(context, complexFormat, angleUnit, target); diff --git a/poincare/src/complex_cartesian.cpp b/poincare/src/complex_cartesian.cpp index 65ea33af3..ccf3d88f1 100644 --- a/poincare/src/complex_cartesian.cpp +++ b/poincare/src/complex_cartesian.cpp @@ -49,7 +49,21 @@ Complex ComplexCartesianNode::templatedApproximate(Context& context, Preferen } assert(a.imag() == 0.0 || std::isnan(a.imag())); assert(b.imag() == 0.0 || std::isnan(b.imag())); - return Complex(a.real(), b.real()); + return Complex::Builder(a.real(), b.real()); +} + +ComplexCartesian ComplexCartesian::Builder() { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(ComplexCartesianNode)); + ComplexCartesianNode * node = new (bufferNode) ComplexCartesianNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); +} + +ComplexCartesian ComplexCartesian::Builder(Expression real, Expression imag) { + ComplexCartesian c = ComplexCartesian::Builder(); + c.replaceChildAtIndexInPlace(0, real); + c.replaceChildAtIndexInPlace(1, imag); + return c; } Expression ComplexCartesian::shallowReduce() { @@ -80,7 +94,7 @@ Expression ComplexCartesian::shallowBeautify(Context & context, Preferences::Com void ComplexCartesian::factorAndArgumentOfFunction(Expression e, ExpressionNode::Type searchedType, Expression * factor, Expression * argument, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { if (e.type() == searchedType) { - *factor = Rational(1); + *factor = Rational::Builder(1); *argument = e.childAtIndex(0); return; } @@ -106,12 +120,12 @@ Expression ComplexCartesian::squareNorm(Context & context, Preferences::ComplexF factorAndArgumentOfFunction(a, ExpressionNode::Type::Cosine, &aFactor, &aArgument, context, complexFormat, angleUnit, target); factorAndArgumentOfFunction(b, ExpressionNode::Type::Sine, &bFactor, &bArgument, context, complexFormat, angleUnit, target); if (!aFactor.isUninitialized() && !aArgument.isUninitialized() && !bFactor.isUninitialized() && !bArgument.isUninitialized() && aFactor.isIdenticalTo(bFactor) && aArgument.isIdenticalTo(bArgument)) { - Power result = Power::Builder(aFactor, Rational(2)); + Power result = Power::Builder(aFactor, Rational::Builder(2)); aFactor.shallowReduce(context, complexFormat, angleUnit, target); return result; } - Expression a2 = Power::Builder(a, Rational(2)); - Expression b2 = Power::Builder(b, Rational(2)); + Expression a2 = Power::Builder(a, Rational::Builder(2)); + Expression b2 = Power::Builder(b, Rational::Builder(2)); Addition add = Addition::Builder(a2, b2); a2.shallowReduce(context, complexFormat, angleUnit, target); b2.shallowReduce(context, complexFormat, angleUnit, target); @@ -152,7 +166,7 @@ Expression ComplexCartesian::argument(Context & context, Preferences::ComplexFor } // Then, compute sign(b) * Pi/2 - arctan(a/b) Expression signb = SignFunction::Builder(b); - Expression signbPi2 = Multiplication::Builder(Rational(1,2), signb, Constant(Ion::Charset::SmallPi)); + Expression signbPi2 = Multiplication::Builder(Rational::Builder(1,2), signb, Constant::Builder(Ion::Charset::SmallPi)); signb.shallowReduce(context, complexFormat, angleUnit, target); Expression sub = Subtraction::Builder(signbPi2, arcTangent); signbPi2.shallowReduce(context, complexFormat, angleUnit, target); @@ -161,9 +175,9 @@ Expression ComplexCartesian::argument(Context & context, Preferences::ComplexFor } else { // if b == 0, argument = (1-sign(a))*Pi/2 Expression signa = SignFunction::Builder(a).shallowReduce(context, complexFormat, angleUnit, target); - Subtraction sub = Subtraction::Builder(Rational(1), signa); + Subtraction sub = Subtraction::Builder(Rational::Builder(1), signa); signa.shallowReduce(context, complexFormat, angleUnit, target); - Multiplication mul = Multiplication::Builder(Rational(1,2), Constant(Ion::Charset::SmallPi), sub); + Multiplication mul = Multiplication::Builder(Rational::Builder(1,2), Constant::Builder(Ion::Charset::SmallPi), sub); sub.shallowReduce(context, complexFormat, angleUnit, target); return mul; } @@ -175,17 +189,17 @@ ComplexCartesian ComplexCartesian::inverse(Context & context, Preferences::Compl // 1/(a+ib) = a/(a^2+b^2)+i*(-b/(a^2+b^2)) Expression denominatorReal = clone().convert().squareNorm(context, complexFormat, angleUnit, target); Expression denominatorImag = denominatorReal.clone(); - Expression denominatorRealInv = Power::Builder(denominatorReal, Rational(-1)); + Expression denominatorRealInv = Power::Builder(denominatorReal, Rational::Builder(-1)); denominatorReal.shallowReduce(context, complexFormat, angleUnit, target); - Expression denominatorImagInv = Power::Builder(denominatorImag, Rational(-1)); + Expression denominatorImagInv = Power::Builder(denominatorImag, Rational::Builder(-1)); denominatorImag.shallowReduce(context, complexFormat, angleUnit, target); Multiplication A = Multiplication::Builder(a, denominatorRealInv); denominatorRealInv.shallowReduce(context, complexFormat, angleUnit, target); - Expression numeratorImag = Multiplication::Builder(Rational(-1), b); + Expression numeratorImag = Multiplication::Builder(Rational::Builder(-1), b); Multiplication B = Multiplication::Builder(numeratorImag, denominatorImagInv); numeratorImag.shallowReduce(context, complexFormat, angleUnit, target); denominatorImagInv.shallowReduce(context, complexFormat, angleUnit, target); - ComplexCartesian result(A,B); + ComplexCartesian result = ComplexCartesian::Builder(A,B); A.shallowReduce(context, complexFormat, angleUnit, target); B.shallowReduce(context, complexFormat, angleUnit, target); return result.interruptComputationIfManyNodes(); @@ -193,11 +207,11 @@ ComplexCartesian ComplexCartesian::inverse(Context & context, Preferences::Compl Multiplication ComplexCartesian::squareRootHelper(Expression e, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { //(1/2)*sqrt(2*e) - Multiplication doubleE = Multiplication::Builder(Rational(2), e); + Multiplication doubleE = Multiplication::Builder(Rational::Builder(2), e); e.shallowReduce(context, complexFormat, angleUnit, target); Expression sqrt = SquareRoot::Builder(doubleE); doubleE.shallowReduce(context, complexFormat, angleUnit, target); - Multiplication result = Multiplication::Builder(Rational(1,2), sqrt); + Multiplication result = Multiplication::Builder(Rational::Builder(1,2), sqrt); sqrt.shallowReduce(context, complexFormat, angleUnit, target); return result; } @@ -238,16 +252,16 @@ ComplexCartesian ComplexCartesian::powerInteger(int n, Context & context, Prefer // (b*i)^n = b^n*i^n with i^n == i, -i, 1 or -1 if (a.isRationalZero()) { ComplexCartesian result; - Expression bpow = Power::Builder(b, Rational(n)); + Expression bpow = Power::Builder(b, Rational::Builder(n)); if (n/2%2 == 1) { - Expression temp = Multiplication::Builder(Rational(-1), bpow); + Expression temp = Multiplication::Builder(Rational::Builder(-1), bpow); bpow.shallowReduce(context, complexFormat, angleUnit, target); bpow = temp; } if (n%2 == 0) { - result = ComplexCartesian(bpow, Rational(0)); + result = ComplexCartesian::Builder(bpow, Rational::Builder(0)); } else { - result = ComplexCartesian(Rational(0), bpow); + result = ComplexCartesian::Builder(Rational::Builder(0), bpow); } bpow.shallowReduce(context, complexFormat, angleUnit, target); return result; @@ -259,17 +273,17 @@ ComplexCartesian ComplexCartesian::powerInteger(int n, Context & context, Prefer Addition B = Addition::Builder(); ComplexCartesian result = ComplexCartesian::Builder(A, B); for (int i = 0; i <= n; i++) { - BinomialCoefficient binom = BinomialCoefficient::Builder(Rational(n), Rational(i)); + BinomialCoefficient binom = BinomialCoefficient::Builder(Rational::Builder(n), Rational::Builder(i)); Expression aclone = i == n ? a : a.clone(); Expression bclone = i == n ? b : b.clone(); - Power apow = Power::Builder(aclone, Rational(n-i)); - Power bpow = Power::Builder(bclone, Rational(i)); + Power apow = Power::Builder(aclone, Rational::Builder(n-i)); + Power bpow = Power::Builder(bclone, Rational::Builder(i)); Multiplication m = Multiplication::Builder(binom, apow, bpow); binom.shallowReduce(); apow.shallowReduce(context, complexFormat, angleUnit, target); bpow.shallowReduce(context, complexFormat, angleUnit, target); if (i/2%2 == 1) { - m.addChildAtIndexInPlace(Rational(-1), 0, m.numberOfChildren()); + m.addChildAtIndexInPlace(Rational::Builder(-1), 0, m.numberOfChildren()); } if (i%2 == 0) { A.addChildAtIndexInPlace(m, A.numberOfChildren(), A.numberOfChildren()); @@ -328,9 +342,9 @@ ComplexCartesian ComplexCartesian::power(ComplexCartesian & other, Context & con // R = r^c*e^(-th*d) Expression rpowc = Power::Builder(rclone, c.clone()); rclone.shallowReduce(context, complexFormat, angleUnit, target); - Expression thmuld = Multiplication::Builder(Rational(-1), thclone, d.clone()); + Expression thmuld = Multiplication::Builder(Rational::Builder(-1), thclone, d.clone()); thclone.shallowReduce(context, complexFormat, angleUnit, target); - Expression exp = Power::Builder(Constant(Ion::Charset::Exponential), thmuld); + Expression exp = Power::Builder(Constant::Builder(Ion::Charset::Exponential), thmuld); thmuld.shallowReduce(context, complexFormat, angleUnit, target); Multiplication norm = Multiplication::Builder(rpowc, exp); rpowc.shallowReduce(context, complexFormat, angleUnit, target); @@ -370,7 +384,7 @@ ComplexCartesian ComplexCartesian::power(ComplexCartesian & other, Context & con ComplexCartesian ComplexCartesian::interruptComputationIfManyNodes() { if (numberOfDescendants(true) > k_maxNumberOfNodesBeforeInterrupting) { Expression::SetInterruption(true); - return ComplexCartesian(Undefined(), Undefined()); + return ComplexCartesian::Builder(Undefined::Builder(), Undefined::Builder()); } return *this; } diff --git a/poincare/src/condensed_sum_layout.cpp b/poincare/src/condensed_sum_layout.cpp index 3204fe357..a658e5d5d 100644 --- a/poincare/src/condensed_sum_layout.cpp +++ b/poincare/src/condensed_sum_layout.cpp @@ -37,4 +37,11 @@ KDPoint CondensedSumLayoutNode::positionOfChild(LayoutNode * child) { return KDPoint(x,y); } -} \ No newline at end of file +CondensedSumLayout CondensedSumLayout::Builder(Layout base, Layout subscript, Layout superscript) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(CondensedSumLayoutNode)); + CondensedSumLayoutNode * node = new (bufferNode) CondensedSumLayoutNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(base, subscript, superscript).array(), 3); + return static_cast(h); +} + +} diff --git a/poincare/src/confidence_interval.cpp b/poincare/src/confidence_interval.cpp index c56b756a2..cc47829ac 100644 --- a/poincare/src/confidence_interval.cpp +++ b/poincare/src/confidence_interval.cpp @@ -41,7 +41,7 @@ Evaluation ConfidenceIntervalNode::templatedApproximate(Context& context, Pre std::complex operands[2]; operands[0] = std::complex(f - 1/std::sqrt(n)); operands[1] = std::complex(f + 1/std::sqrt(n)); - return MatrixComplex(operands, 1, 2); + return MatrixComplex::Builder(operands, 1, 2); } Layout SimplePredictionIntervalNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { @@ -52,6 +52,13 @@ int SimplePredictionIntervalNode::serialize(char * buffer, int bufferSize, Prefe return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, SimplePredictionInterval::s_functionHelper.name()); } +ConfidenceInterval ConfidenceInterval::Builder(Expression child0, Expression child1) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(ConfidenceIntervalNode)); + ConfidenceIntervalNode * node = new (bufferNode) ConfidenceIntervalNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(child0, child1).array(), 2); + return static_cast(h); +} + Expression ConfidenceInterval::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { { Expression e = Expression::defaultShallowReduce(); @@ -63,13 +70,13 @@ Expression ConfidenceInterval::shallowReduce(Context & context, Preferences::Com Expression c1 = childAtIndex(1); #if MATRIX_EXACT_REDUCING if (c0.type() == ExpressionNode::Type::Matrix || c1.type() == ExpressionNode::Type::Matrix) { - return Undefined(); + return Undefined::Builder(); } #endif if (c0.type() == ExpressionNode::Type::Rational) { Rational r0 = static_cast(c0); if (r0.signedIntegerNumerator().isNegative() || Integer::NaturalOrder(r0.signedIntegerNumerator(), r0.integerDenominator()) > 0) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -77,7 +84,7 @@ Expression ConfidenceInterval::shallowReduce(Context & context, Preferences::Com if (c1.type() == ExpressionNode::Type::Rational) { Rational r1 = static_cast(c1); if (!r1.integerDenominator().isOne() || r1.signedIntegerNumerator().isNegative()) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -88,9 +95,9 @@ Expression ConfidenceInterval::shallowReduce(Context & context, Preferences::Com Rational r0 = static_cast(c0); Rational r1 = static_cast(c1); // Compute [r0-1/sqr(r1), r0+1/sqr(r1)] - Expression sqr = Power::Builder(r1, Rational(-1, 2)); + Expression sqr = Power::Builder(r1, Rational::Builder(-1, 2)); Matrix matrix = Matrix::Builder(); - matrix.addChildAtIndexInPlace(Addition::Builder(r0.clone(), Multiplication::Builder(Rational(-1), sqr.clone())), 0, 0); + matrix.addChildAtIndexInPlace(Addition::Builder(r0.clone(), Multiplication::Builder(Rational::Builder(-1), sqr.clone())), 0, 0); matrix.addChildAtIndexInPlace(Addition::Builder(r0, sqr), 1, 1); matrix.setDimensions(1, 2); replaceWithInPlace(matrix); @@ -98,4 +105,11 @@ Expression ConfidenceInterval::shallowReduce(Context & context, Preferences::Com return matrix; } +SimplePredictionInterval SimplePredictionInterval::Builder(Expression child0, Expression child1) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(SimplePredictionIntervalNode)); + SimplePredictionIntervalNode * node = new (bufferNode) SimplePredictionIntervalNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(child0, child1).array(), 2); + return static_cast(h); +} + } diff --git a/poincare/src/conjugate.cpp b/poincare/src/conjugate.cpp index 27ed8cc88..a5f40eabf 100644 --- a/poincare/src/conjugate.cpp +++ b/poincare/src/conjugate.cpp @@ -29,7 +29,7 @@ Expression ConjugateNode::shallowReduce(Context & context, Preferences::ComplexF template Complex ConjugateNode::computeOnComplex(const std::complex c, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) { - return Complex(std::conj(c)); + return Complex::Builder(std::conj(c)); } Expression Conjugate::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { @@ -51,7 +51,7 @@ Expression Conjugate::shallowReduce(Context & context, Preferences::ComplexForma } if (c.type() == ExpressionNode::Type::ComplexCartesian) { ComplexCartesian complexChild = static_cast(c); - Multiplication m = Multiplication::Builder(Rational(-1), complexChild.imag()); + Multiplication m = Multiplication::Builder(Rational::Builder(-1), complexChild.imag()); complexChild.replaceChildAtIndexInPlace(1, m); m.shallowReduce(context, complexFormat, angleUnit, target); replaceWithInPlace(complexChild); @@ -64,4 +64,11 @@ Expression Conjugate::shallowReduce(Context & context, Preferences::ComplexForma return *this; } +Conjugate Conjugate::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(ConjugateNode)); + ConjugateNode * node = new (bufferNode) ConjugateNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + } diff --git a/poincare/src/conjugate_layout.cpp b/poincare/src/conjugate_layout.cpp index ac636dcad..2522718aa 100644 --- a/poincare/src/conjugate_layout.cpp +++ b/poincare/src/conjugate_layout.cpp @@ -104,4 +104,11 @@ bool ConjugateLayoutNode::willReplaceChild(LayoutNode * oldChild, LayoutNode * n return true; } +ConjugateLayout ConjugateLayout::Builder(Layout child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(ConjugateLayoutNode)); + ConjugateLayoutNode * node = new (bufferNode) ConjugateLayoutNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + } diff --git a/poincare/src/constant.cpp b/poincare/src/constant.cpp index a6df6544e..cdc28aebb 100644 --- a/poincare/src/constant.cpp +++ b/poincare/src/constant.cpp @@ -11,6 +11,10 @@ namespace Poincare { +ConstantNode::ConstantNode(const char * newName, int length) : SymbolAbstractNode() { + strlcpy(const_cast(name()), newName, length+1); +} + ExpressionNode::Sign ConstantNode::sign(Context * context) const { if (isPi() || isExponential()) { return Sign::Positive; @@ -59,29 +63,32 @@ template Evaluation ConstantNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { if (isIComplex()) { assert(m_name[1] == 0); - return Complex(0.0, 1.0); + return Complex::Builder(0.0, 1.0); } if (isPi()) { - return Complex(M_PI); + return Complex::Builder(M_PI); } assert(isExponential()); - return Complex(M_E); + return Complex::Builder(M_E); } Expression ConstantNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { return Constant(this).shallowReduce(context, complexFormat, angleUnit, target); } -Constant::Constant(char name) : SymbolAbstract(TreePool::sharedPool()->createTreeNode(SymbolAbstract::AlignedNodeSize(1, sizeof(ConstantNode)))) { - node()->setName(&name, 1); +Constant Constant::Builder(char name) { + void * bufferNode = TreePool::sharedPool()->alloc(SymbolAbstract::AlignedNodeSize(1, sizeof(ConstantNode))); + ConstantNode * node = new (bufferNode) ConstantNode(&name, 1); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); } Expression Constant::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { Expression result; if (complexFormat == Preferences::ComplexFormat::Real && isIComplex()) { - result = Unreal(); + result = Unreal::Builder(); } else if (target == ExpressionNode::ReductionTarget::User && isIComplex()) { - result = ComplexCartesian::Builder(Rational(0), Rational(1)); + result = ComplexCartesian::Builder(Rational::Builder(0), Rational::Builder(1)); } if (!result.isUninitialized()) { replaceWithInPlace(result); diff --git a/poincare/src/cosine.cpp b/poincare/src/cosine.cpp index b0070ff20..46e0a90eb 100644 --- a/poincare/src/cosine.cpp +++ b/poincare/src/cosine.cpp @@ -19,7 +19,7 @@ template Complex CosineNode::computeOnComplex(const std::complex c, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) { std::complex angleInput = Trigonometry::ConvertToRadian(c, angleUnit); std::complex res = std::cos(angleInput); - return Complex(Trigonometry::RoundToMeaningfulDigits(res, angleInput)); + return Complex::Builder(Trigonometry::RoundToMeaningfulDigits(res, angleInput)); } Layout CosineNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { @@ -50,4 +50,11 @@ Expression Cosine::shallowReduce(Context & context, Preferences::ComplexFormat c return Trigonometry::shallowReduceDirectFunction(*this, context, complexFormat, angleUnit, target); } +Cosine Cosine::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(CosineNode)); + CosineNode * node = new (bufferNode) CosineNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + } diff --git a/poincare/src/decimal.cpp b/poincare/src/decimal.cpp index 8272a2a79..f883333c1 100644 --- a/poincare/src/decimal.cpp +++ b/poincare/src/decimal.cpp @@ -25,10 +25,11 @@ void removeZeroAtTheEnd(Integer * i) { assert(!i->isOverflow()); } -void DecimalNode::setValue(const native_uint_t * mantissaDigits, uint8_t mantissaSize, int exponent, bool negative) { - m_negative = negative; - m_exponent = exponent; - m_numberOfDigitsInMantissa = mantissaSize; +DecimalNode::DecimalNode(const native_uint_t * mantissaDigits, uint8_t mantissaSize, int exponent, bool negative) : + m_negative(negative), + m_exponent(exponent), + m_numberOfDigitsInMantissa(mantissaSize) +{ memcpy(m_mantissa, mantissaDigits, mantissaSize*sizeof(native_uint_t)); } @@ -40,14 +41,6 @@ Integer DecimalNode::unsignedMantissa() const { return Integer::BuildInteger((native_uint_t *)m_mantissa, m_numberOfDigitsInMantissa, false); } -void DecimalNode::initToMatchSize(size_t goalSize) { - assert(goalSize != sizeof(DecimalNode)); - int mantissaSize = goalSize - sizeof(DecimalNode); - assert(mantissaSize%sizeof(native_uint_t) == 0); - m_numberOfDigitsInMantissa = mantissaSize/sizeof(native_uint_t); - assert(size() == goalSize); -} - static size_t DecimalSize(uint8_t numberOfDigitsInMantissa) { return sizeof(DecimalNode)+ sizeof(native_uint_t)*numberOfDigitsInMantissa; } @@ -268,7 +261,7 @@ int Decimal::Exponent(const char * integralPart, int integralPartLength, const c return exp; } -Decimal::Decimal(const char * integralPart, int integralPartLength, const char * fractionalPart, int fractionalPartLength, int exponent) : Number() { +Decimal Decimal::Builder(const char * integralPart, int integralPartLength, const char * fractionalPart, int fractionalPartLength, int exponent) { /* Create a Decimal whose mantissa has less than * k_numberOfStoredSignificantDigits. We round exceeding number if necessary. */ Integer zero(0); @@ -301,11 +294,11 @@ Decimal::Decimal(const char * integralPart, int integralPartLength, const char * } numerator = rounding ? Integer::Addition(numerator, Integer(1)) : numerator; exponent = numerator.isZero() ? 0 : exponent; - new (this) Decimal(numerator, exponent); + return Decimal::Builder(numerator, exponent); } template -Decimal::Decimal(T f) : Number() { +Decimal Decimal::Builder(T f) { assert(!std::isnan(f) && !std::isinf(f)); int exp = IEEE754::exponentBase10(f); /* We keep 7 significant digits for if the the Decimal was built from a float @@ -327,17 +320,20 @@ Decimal::Decimal(T f) : Number() { Integer m = Integer((int64_t)(std::round(mantissaf))); /* We get rid of extra 0 at the end of the mantissa. */ removeZeroAtTheEnd(&m); - new (this) Decimal(m, exp); + return Decimal::Builder(m, exp); } /* We do not get rid of the useless 0s ending the mantissa here because we want * to keep them if they were entered by the user. */ -Decimal::Decimal(Integer m, int e) : - Decimal(DecimalSize(m.numberOfDigits()), m, e) {} +Decimal Decimal::Builder(Integer m, int e) { + return Decimal::Builder(DecimalSize(m.numberOfDigits()), m, e); +} - -Decimal::Decimal(size_t size, const Integer & m, int e) : Number(TreePool::sharedPool()->createTreeNode(size)) { - node()->setValue(m.digits(), m.numberOfDigits(), e, m.isNegative()); +Decimal Decimal::Builder(size_t size, const Integer & m, int e) { + void * bufferNode = TreePool::sharedPool()->alloc(size); + DecimalNode * node = new (bufferNode) DecimalNode(m.digits(), m.numberOfDigits(), e, m.isNegative()); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); } Expression Decimal::setSign(ExpressionNode::Sign s) { @@ -369,7 +365,7 @@ Expression Decimal::shallowReduce() { if (numerator.isOverflow() || denominator.isOverflow()) { result = Number::FloatNumber(node()->signedMantissa().template approximate()*std::pow(10.0, (double)exp)); } else { - result = Rational(numerator, denominator); + result = Rational::Builder(numerator, denominator); } replaceWithInPlace(result); return result; @@ -386,7 +382,7 @@ Expression Decimal::shallowBeautify() { return *this; } -template Decimal::Decimal(double); -template Decimal::Decimal(float); +template Decimal Decimal::Decimal::Builder(double); +template Decimal Decimal::Decimal::Builder(float); } diff --git a/poincare/src/derivative.cpp b/poincare/src/derivative.cpp index fffecd1b1..426878745 100644 --- a/poincare/src/derivative.cpp +++ b/poincare/src/derivative.cpp @@ -67,10 +67,10 @@ Evaluation DerivativeNode::templatedApproximate(Context& context, Preferences return Complex::Undefined(); } if (std::fabs(error) < min) { - return Complex(result); + return Complex::Builder(result); } error = std::pow((T)10, std::floor(std::log10(std::fabs(error)))+2); - return Complex(std::round(result/error)*error); + return Complex::Builder(std::round(result/error)*error); } template @@ -149,11 +149,18 @@ Expression Derivative::shallowReduce() { } #if MATRIX_EXACT_REDUCING if (childAtIndex(0).type() == ExpressionNode::Type::Matrix || || childAtIndex(1).type() == ExpressionNode::Type::Matrix || childAtIndex(2).type() == ExpressionNode::Type::Matrix) { - return Undefined(); + return Undefined::Builder(); } #endif // TODO: to be implemented diff(+) -> +diff() etc return *this; } +Derivative Derivative::Builder(Expression child0, Symbol child1, Expression child2) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(DerivativeNode)); + DerivativeNode * node = new (bufferNode) DerivativeNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(child0, child1, child2).array(), 3); + return static_cast(h); +} + } diff --git a/poincare/src/determinant.cpp b/poincare/src/determinant.cpp index dae48be91..e0b973e25 100644 --- a/poincare/src/determinant.cpp +++ b/poincare/src/determinant.cpp @@ -25,13 +25,20 @@ int DeterminantNode::serialize(char * buffer, int bufferSize, Preferences::Print template Evaluation DeterminantNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation input = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); - return Complex(input.determinant()); + return Complex::Builder(input.determinant()); } Expression DeterminantNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { return Determinant(this).shallowReduce(context); } +Determinant Determinant::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(DeterminantNode)); + DeterminantNode * node = new (bufferNode) DeterminantNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + Expression Determinant::shallowReduce(Context & context) { { Expression e = Expression::defaultShallowReduce(); diff --git a/poincare/src/division.cpp b/poincare/src/division.cpp index 48c6734c1..8a6f5bb49 100644 --- a/poincare/src/division.cpp +++ b/poincare/src/division.cpp @@ -50,7 +50,7 @@ template Complex DivisionNode::compute(const std::complex c, c if (d.real() == 0.0 && d.imag() == 0.0) { return Complex::Undefined(); } - return Complex(c/d); + return Complex::Builder(c/d); } template MatrixComplex DivisionNode::computeOnComplexAndMatrix(const std::complex c, const MatrixComplex n, Preferences::ComplexFormat complexFormat) { @@ -70,6 +70,20 @@ template MatrixComplex DivisionNode::computeOnMatrices(const Matr // Division +Division Division::Builder() { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(DivisionNode)); + DivisionNode * node = new (bufferNode) DivisionNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); +} + +Division Division::Builder(Expression numerator, Expression denominator) { + Division d = Division::Builder(); + d.replaceChildAtIndexInPlace(0, numerator); + d.replaceChildAtIndexInPlace(1, denominator); + return d; +} + Expression Division::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { { Expression e = Expression::defaultShallowReduce(); @@ -77,7 +91,7 @@ Expression Division::shallowReduce(Context & context, Preferences::ComplexFormat return e; } } - Expression p = Power::Builder(childAtIndex(1), Rational(-1)); + Expression p = Power::Builder(childAtIndex(1), Rational::Builder(-1)); Multiplication m = Multiplication::Builder(childAtIndex(0), p); p.shallowReduce(context, complexFormat, angleUnit, target); // Imagine Division::Builder(2,1). p would be 1^(-1) which can be simplified replaceWithInPlace(m); diff --git a/poincare/src/division_quotient.cpp b/poincare/src/division_quotient.cpp index f5ca4f543..b382a54cc 100644 --- a/poincare/src/division_quotient.cpp +++ b/poincare/src/division_quotient.cpp @@ -32,7 +32,14 @@ Evaluation DivisionQuotientNode::templatedApproximate(Context& context, Prefe if (std::isnan(f1) || std::isnan(f2) || f1 != (int)f1 || f2 != (int)f2) { return Complex::Undefined(); } - return Complex(std::floor(f1/f2)); + return Complex::Builder(std::floor(f1/f2)); +} + +DivisionQuotient DivisionQuotient::Builder(Expression child0, Expression child1) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(DivisionQuotientNode)); + DivisionQuotientNode * node = new (bufferNode) DivisionQuotientNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(child0, child1).array(), 2); + return static_cast(h); } Expression DivisionQuotient::shallowReduce() { @@ -46,7 +53,7 @@ Expression DivisionQuotient::shallowReduce() { Expression c1 = childAtIndex(1); #if MATRIX_EXACT_REDUCING if (c0.type() == ExpressionNode::Type::Matrix || c1.type() == ExpressionNode::Type::Matrix) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -54,7 +61,7 @@ Expression DivisionQuotient::shallowReduce() { if (c0.type() == ExpressionNode::Type::Rational) { Rational r0 = static_cast(c0); if (!r0.integerDenominator().isOne()) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -62,7 +69,7 @@ Expression DivisionQuotient::shallowReduce() { if (c1.type() == ExpressionNode::Type::Rational) { Rational r1 = static_cast(c1); if (!r1.integerDenominator().isOne()) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -76,13 +83,13 @@ Expression DivisionQuotient::shallowReduce() { Integer a = r0.signedIntegerNumerator(); Integer b = r1.signedIntegerNumerator(); if (b.isZero()) { - Expression result = Infinity(a.isNegative()); + Expression result = Infinity::Builder(a.isNegative()); replaceWithInPlace(result); return result; } Integer result = Integer::Division(a, b).quotient; assert(!result.isOverflow()); - Expression rationalResult = Rational(result); + Expression rationalResult = Rational::Builder(result); replaceWithInPlace(rationalResult); return rationalResult; } diff --git a/poincare/src/division_remainder.cpp b/poincare/src/division_remainder.cpp index 976d2f16f..030fb33ca 100644 --- a/poincare/src/division_remainder.cpp +++ b/poincare/src/division_remainder.cpp @@ -33,7 +33,14 @@ Evaluation DivisionRemainderNode::templatedApproximate(Context& context, Pref if (std::isnan(f1) || std::isnan(f2) || f1 != (int)f1 || f2 != (int)f2) { return Complex::Undefined(); } - return Complex(std::round(f1-f2*std::floor(f1/f2))); + return Complex::Builder(std::round(f1-f2*std::floor(f1/f2))); +} + +DivisionRemainder DivisionRemainder::Builder(Expression child0, Expression child1) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(DivisionRemainderNode)); + DivisionRemainderNode * node = new (bufferNode) DivisionRemainderNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(child0, child1).array(), 2); + return static_cast(h); } Expression DivisionRemainder::shallowReduce() { @@ -47,13 +54,13 @@ Expression DivisionRemainder::shallowReduce() { Expression c1 = childAtIndex(1); #if MATRIX_EXACT_REDUCING if (c0.type() == ExpressionNode::Type::Matrix || c1.type() == ExpressionNode::Type::Matrix) { - return Undefined(); + return Undefined::Builder(); } #endif if (c0.type() == ExpressionNode::Type::Rational) { Rational r0 = static_cast(c0); if (!r0.integerDenominator().isOne()) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -61,7 +68,7 @@ Expression DivisionRemainder::shallowReduce() { if (c1.type() == ExpressionNode::Type::Rational) { Rational r1 = static_cast(c1); if (!r1.integerDenominator().isOne()) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -75,13 +82,13 @@ Expression DivisionRemainder::shallowReduce() { Integer a = r0.signedIntegerNumerator(); Integer b = r1.signedIntegerNumerator(); if (b.isZero()) { - Expression result = Infinity(a.isNegative()); + Expression result = Infinity::Builder(a.isNegative()); replaceWithInPlace(result); return result; } Integer result = Integer::Division(a, b).remainder; assert(!result.isOverflow()); - Expression rationalResult = Rational(result); + Expression rationalResult = Rational::Builder(result); replaceWithInPlace(rationalResult); return rationalResult; } diff --git a/poincare/src/empty_expression.cpp b/poincare/src/empty_expression.cpp index 4cb841349..cf007c671 100644 --- a/poincare/src/empty_expression.cpp +++ b/poincare/src/empty_expression.cpp @@ -11,13 +11,18 @@ int EmptyExpressionNode::serialize(char * buffer, int bufferSize, Preferences::P } Layout EmptyExpressionNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return EmptyLayout(); + return EmptyLayout::Builder(); } template Evaluation EmptyExpressionNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { return Complex::Undefined(); } -EmptyExpression::EmptyExpression() : Expression(TreePool::sharedPool()->createTreeNode()) {} +EmptyExpression EmptyExpression::Builder() { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(EmptyExpressionNode)); + EmptyExpressionNode * node = new (bufferNode) EmptyExpressionNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); +} } diff --git a/poincare/src/empty_layout.cpp b/poincare/src/empty_layout.cpp index 00f0b642b..f8a0f8f3b 100644 --- a/poincare/src/empty_layout.cpp +++ b/poincare/src/empty_layout.cpp @@ -95,13 +95,12 @@ void EmptyLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expressionColor } EmptyLayout::EmptyLayout(const EmptyLayoutNode * n) : Layout(n) {} -EmptyLayout::EmptyLayout(EmptyLayoutNode::Color color, bool visible, const KDFont * font, bool margins) : - Layout(TreePool::sharedPool()->createTreeNode()) -{ - node()->setColor(color); - node()->setVisible(visible); - node()->setFont(font); - node()->setMargins(margins); + +EmptyLayout EmptyLayout::Builder(EmptyLayoutNode::Color color, bool visible, const KDFont * font, bool margins) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(EmptyLayoutNode)); + EmptyLayoutNode * node = new (bufferNode) EmptyLayoutNode(color, visible, font, margins); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); } } diff --git a/poincare/src/equal.cpp b/poincare/src/equal.cpp index dbcb1abaa..e3f9f0c3d 100644 --- a/poincare/src/equal.cpp +++ b/poincare/src/equal.cpp @@ -27,7 +27,7 @@ Expression EqualNode::shallowReduce(Context & context, Preferences::ComplexForma Layout EqualNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { HorizontalLayout result = HorizontalLayout::Builder(); result.addOrMergeChildAtIndex(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits), 0, false); - result.addChildAtIndex(CharLayout('='), result.numberOfChildren(), result.numberOfChildren(), nullptr); + result.addChildAtIndex(CharLayout::Builder('='), result.numberOfChildren(), result.numberOfChildren(), nullptr); result.addOrMergeChildAtIndex(childAtIndex(1)->createLayout(floatDisplayMode, numberOfSignificantDigits), result.numberOfChildren(), false); return result; } @@ -41,6 +41,13 @@ Evaluation EqualNode::templatedApproximate(Context& context, Preferences::Com return Complex::Undefined(); } +Equal Equal::Builder(Expression child0, Expression child1) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(EqualNode)); + EqualNode * node = new (bufferNode) EqualNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(child0, child1).array(), 2); + return static_cast(h); +} + Expression Equal::standardEquation(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Expression sub = Subtraction::Builder(childAtIndex(0).clone(), childAtIndex(1).clone()); return sub.reduce(context, complexFormat, angleUnit); @@ -54,7 +61,7 @@ Expression Equal::shallowReduce() { } } if (childAtIndex(0).isIdenticalTo(childAtIndex(1))) { - Expression result = Rational(1); + Expression result = Rational::Builder(1); replaceWithInPlace(result); return result; } diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index 544814670..b11eb1a6c 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -166,7 +166,7 @@ bool Expression::getLinearCoefficients(char * variables, int maxVariableSize, Ex int degree = equation.getPolynomialReducedCoefficients(&variables[index*maxVariableSize], polynomialCoefficients, context, complexFormat, angleUnit); switch (degree) { case 0: - coefficients[index] = Rational(0); + coefficients[index] = Rational::Builder(0); break; case 1: coefficients[index] = polynomialCoefficients[1]; @@ -213,10 +213,10 @@ Expression Expression::defaultShallowReduce() { // - the result is unreal is at least one child is unreal // - the result is undefined is at least one child is undefined but no child is unreal if (childAtIndex(i).type() == ExpressionNode::Type::Unreal) { - result = Unreal(); + result = Unreal::Builder(); break; } else if (childAtIndex(i).type() == ExpressionNode::Type::Undefined) { - result = Undefined(); + result = Undefined::Builder(); } } if (!result.isUninitialized()) { @@ -369,7 +369,7 @@ bool Expression::isEqualToItsApproximationLayout(Expression approximation, char * to re-serialize it because the number of stored significative * numbers and the number of displayed significative numbers might not be * identical. (For example, 0.000025 might be displayed "0.00003" and stored - * as Decimal(0.000025) and isEqualToItsApproximationLayout should return + * as Decimal::Builder(0.000025) and isEqualToItsApproximationLayout should return * false) */ Expression approximateOutput = Expression::ParseAndSimplify(buffer, context, complexFormat, angleUnit); bool equal = isIdenticalTo(approximateOutput); @@ -389,7 +389,7 @@ int Expression::serialize(char * buffer, int bufferSize, Preferences::PrintFloat Expression Expression::ParseAndSimplify(const char * text, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { Expression exp = Parse(text); if (exp.isUninitialized()) { - return Undefined(); + return Undefined::Builder(); } exp = exp.simplify(context, complexFormat, angleUnit); /* simplify might have been interrupted, in which case the resulting @@ -404,8 +404,8 @@ void Expression::ParseAndSimplifyAndApproximate(const char * text, Expression * assert(simplifiedExpression); Expression exp = Parse(text); if (exp.isUninitialized()) { - *simplifiedExpression = Undefined(); - *approximateExpression = Undefined(); + *simplifiedExpression = Undefined::Builder(); + *approximateExpression = Undefined::Builder(); return; } exp.simplifyAndApproximate(simplifiedExpression, approximateExpression, context, complexFormat, angleUnit); @@ -449,14 +449,14 @@ void Expression::simplifyAndApproximate(Expression * simplifiedExpression, Expre /* Case 1: the reduced expression is ComplexCartesian or pure real, we can * take into account the complex format to display a+i*b or r*e^(i*th) */ if (e.type() == ExpressionNode::Type::ComplexCartesian || e.isReal(context)) { - ComplexCartesian ecomplex = e.type() == ExpressionNode::Type::ComplexCartesian ? static_cast(e) : ComplexCartesian::Builder(e, Rational(0)); + ComplexCartesian ecomplex = e.type() == ExpressionNode::Type::ComplexCartesian ? static_cast(e) : ComplexCartesian::Builder(e, Rational::Builder(0)); if (approximateExpression) { /* Step 2: Approximation * We compute the approximate expression from the Cartesian form to avoid - * unprecision. For example, if the result is the ComplexCartesian(a,b), + * unprecision. For example, if the result is the ComplexCartesian::Builder(a,b), * the final expression is goind to be sqrt(a^2+b^2)*exp(i*arctan(b/a)... * in Polar ComplexFormat. If we approximate this expression instead of - * ComplexCartesian(a,b), we are going to loose precision on the resulting + * ComplexCartesian::Builder(a,b), we are going to loose precision on the resulting * complex.*/ // Clone the ComplexCartesian to use it to compute the approximation ComplexCartesian ecomplexClone = ecomplex.clone().convert(); @@ -519,12 +519,12 @@ Expression Expression::ExpressionWithoutSymbols(Expression e, Context & context) Expression Expression::radianToDegree() { // e*180/Pi - return Multiplication::Builder(*this, Rational(180), Power::Builder(Constant(Ion::Charset::SmallPi), Rational(-1))); + return Multiplication::Builder(*this, Rational::Builder(180), Power::Builder(Constant::Builder(Ion::Charset::SmallPi), Rational::Builder(-1))); } Expression Expression::degreeToRadian() { // e*Pi/180 - return Multiplication::Builder(*this, Rational(1, 180), Constant(Ion::Charset::SmallPi)); + return Multiplication::Builder(*this, Rational::Builder(1, 180), Constant::Builder(Ion::Charset::SmallPi)); } Expression Expression::reduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { @@ -566,7 +566,7 @@ Expression Expression::setSign(ExpressionNode::Sign s, Context * context, Prefer template Expression Expression::approximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { - return isUninitialized() ? Undefined() : approximateToEvaluation(context, complexFormat, angleUnit).complexToExpression(complexFormat); + return isUninitialized() ? Undefined::Builder() : approximateToEvaluation(context, complexFormat, angleUnit).complexToExpression(complexFormat); } @@ -609,7 +609,7 @@ bool Expression::IsMinusOne(const Expression e) { Expression Expression::CreateComplexExpression(Expression ra, Expression tb, Preferences::ComplexFormat complexFormat, bool undefined, bool isZeroRa, bool isOneRa, bool isZeroTb, bool isOneTb, bool isNegativeRa, bool isNegativeTb) { if (undefined) { - return Undefined(); + return Undefined::Builder(); } switch (complexFormat) { case Preferences::ComplexFormat::Real: @@ -626,9 +626,9 @@ Expression Expression::CreateComplexExpression(Expression ra, Expression tb, Pre } if (!isZeroTb) { if (isOneTb) { - imag = Constant(Ion::Charset::IComplex); + imag = Constant::Builder(Ion::Charset::IComplex); } else { - imag = Multiplication::Builder(tb , Constant(Ion::Charset::IComplex)); + imag = Multiplication::Builder(tb , Constant::Builder(Ion::Charset::IComplex)); } } if (imag.isUninitialized()) { @@ -657,14 +657,14 @@ Expression Expression::CreateComplexExpression(Expression ra, Expression tb, Pre if (!isZeroRa && !isZeroTb) { Expression arg; if (isOneTb) { - arg = Constant(Ion::Charset::IComplex); + arg = Constant::Builder(Ion::Charset::IComplex); } else { - arg = Multiplication::Builder(tb, Constant(Ion::Charset::IComplex)); + arg = Multiplication::Builder(tb, Constant::Builder(Ion::Charset::IComplex)); } if (isNegativeTb) { arg = Opposite::Builder(arg); } - exp = Power::Builder(Constant(Ion::Charset::Exponential), arg); + exp = Power::Builder(Constant::Builder(Ion::Charset::Exponential), arg); } if (exp.isUninitialized()) { return norm; diff --git a/poincare/src/factor.cpp b/poincare/src/factor.cpp index d303b3a06..dd8e005c0 100644 --- a/poincare/src/factor.cpp +++ b/poincare/src/factor.cpp @@ -30,10 +30,17 @@ Expression FactorNode::shallowBeautify(Context & context, Preferences::ComplexFo return Factor(this).shallowBeautify(context, complexFormat, angleUnit); } +Factor Factor::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(FactorNode)); + FactorNode * node = new (bufferNode) FactorNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + Expression Factor::shallowBeautify(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { Expression c = childAtIndex(0); if (c.type() != ExpressionNode::Type::Rational) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -44,7 +51,7 @@ Expression Factor::shallowBeautify(Context & context, Preferences::ComplexFormat } Multiplication numeratorDecomp = createMultiplicationOfIntegerPrimeDecomposition(r.unsignedIntegerNumerator(), context, complexFormat, angleUnit); if (numeratorDecomp.numberOfChildren() == 0) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -52,7 +59,7 @@ Expression Factor::shallowBeautify(Context & context, Preferences::ComplexFormat if (!r.integerDenominator().isOne()) { Multiplication denominatorDecomp = createMultiplicationOfIntegerPrimeDecomposition(r.integerDenominator(), context, complexFormat, angleUnit); if (denominatorDecomp.numberOfChildren() == 0) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -73,7 +80,7 @@ Multiplication Factor::createMultiplicationOfIntegerPrimeDecomposition(Integer i Integer coefficients[Arithmetic::k_maxNumberOfPrimeFactors]; int numberOfPrimeFactors = Arithmetic::PrimeFactorization(i, factors, coefficients, Arithmetic::k_maxNumberOfPrimeFactors); if (numberOfPrimeFactors == 0) { - m.addChildAtIndexInPlace(Rational(i), 0, 0); + m.addChildAtIndexInPlace(Rational::Builder(i), 0, 0); return m; } if (numberOfPrimeFactors < 0) { @@ -81,9 +88,9 @@ Multiplication Factor::createMultiplicationOfIntegerPrimeDecomposition(Integer i return m; } for (int index = 0; index < numberOfPrimeFactors; index++) { - Expression factor = Rational(factors[index]); + Expression factor = Rational::Builder(factors[index]); if (!coefficients[index].isOne()) { - factor = Power::Builder(factor, Rational(coefficients[index])); + factor = Power::Builder(factor, Rational::Builder(coefficients[index])); } m.addChildAtIndexInPlace(factor, m.numberOfChildren(), m.numberOfChildren()); } diff --git a/poincare/src/factorial.cpp b/poincare/src/factorial.cpp index 94a03f10b..47786a22b 100644 --- a/poincare/src/factorial.cpp +++ b/poincare/src/factorial.cpp @@ -52,17 +52,17 @@ Complex FactorialNode::computeOnComplex(const std::complex c, Preferences: for (int i = 1; i <= (int)n; i++) { result *= (T)i; if (std::isinf(result)) { - return Complex(result); + return Complex::Builder(result); } } - return Complex(std::round(result)); + return Complex::Builder(std::round(result)); } Layout FactorialNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { HorizontalLayout result = HorizontalLayout::Builder(); result.addOrMergeChildAtIndex(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits), 0, false); int childrenCount = result.numberOfChildren(); - result.addChildAtIndex(CharLayout('!'), childrenCount, childrenCount, nullptr); + result.addChildAtIndex(CharLayout::Builder('!'), childrenCount, childrenCount, nullptr); return result; } @@ -89,6 +89,13 @@ int FactorialNode::serialize(char * buffer, int bufferSize, Preferences::PrintFl return numberOfChar; } +Factorial Factorial::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(FactorialNode)); + FactorialNode * node = new (bufferNode) FactorialNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + Expression Factorial::shallowReduce() { { Expression e = Expression::defaultShallowReduce(); @@ -104,21 +111,21 @@ Expression Factorial::shallowReduce() { if (childAtIndex(0).type() == ExpressionNode::Type::Rational) { Rational r = childAtIndex(0).convert(); if (!r.integerDenominator().isOne() || r.sign() == ExpressionNode::Sign::Negative) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } if (Integer(k_maxOperandValue).isLowerThan(r.unsignedIntegerNumerator())) { return *this; } - Rational fact = Rational(Integer::Factorial(r.unsignedIntegerNumerator())); + Rational fact = Rational::Builder(Integer::Factorial(r.unsignedIntegerNumerator())); assert(!fact.numeratorOrDenominatorIsInfinity()); // because fact < k_maxOperandValue! replaceWithInPlace(fact); return fact; } if (childAtIndex(0).type() == ExpressionNode::Type::Constant) { // e! = undef, i! = undef, pi! = undef - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } diff --git a/poincare/src/float.cpp b/poincare/src/float.cpp index b18b88ec4..1a37e4107 100644 --- a/poincare/src/float.cpp +++ b/poincare/src/float.cpp @@ -8,7 +8,7 @@ Expression FloatNode::setSign(Sign s, Context * context, Preferences::Complex assert(s == ExpressionNode::Sign::Positive || s == ExpressionNode::Sign::Negative); Sign currentSign = m_value < 0 ? Sign::Negative : Sign::Positive; Expression thisExpr = Number(this); - Expression result = Float(s == currentSign ? m_value : -m_value); + Expression result = Float::Builder(s == currentSign ? m_value : -m_value); thisExpr.replaceWithInPlace(result); return result; } @@ -42,14 +42,17 @@ Layout FloatNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, } template -Float::Float(T value) : Number(TreePool::sharedPool()->createTreeNode>()) { - node()->setFloat(value); +Float Float::Builder(T value) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(FloatNode)); + FloatNode * node = new (bufferNode) FloatNode(value); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); } template class FloatNode; template class FloatNode; -template Float::Float(float value); -template Float::Float(double value); +template Float Float::Builder(float value); +template Float Float::Builder(double value); } diff --git a/poincare/src/floor.cpp b/poincare/src/floor.cpp index 8694f4509..207e1c28e 100644 --- a/poincare/src/floor.cpp +++ b/poincare/src/floor.cpp @@ -28,13 +28,20 @@ Complex FloorNode::computeOnComplex(const std::complex c, Preferences::Com if (c.imag() != 0) { return Complex::Undefined(); } - return Complex(std::floor(c.real())); + return Complex::Builder(std::floor(c.real())); } Expression FloorNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { return Floor(this).shallowReduce(); } +Floor Floor::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(FloorNode)); + FloorNode * node = new (bufferNode) FloorNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + Expression Floor::shallowReduce() { { Expression e = Expression::defaultShallowReduce(); @@ -52,10 +59,10 @@ Expression Floor::shallowReduce() { Constant s = static_cast(c); Expression result; if (s.isPi()) { - result = Rational(3); + result = Rational::Builder(3); } if (s.isExponential()) { - result = Rational(2); + result = Rational::Builder(2); } if (!result.isUninitialized()) { replaceWithInPlace(result); @@ -69,7 +76,7 @@ Expression Floor::shallowReduce() { Rational r = static_cast(c); IntegerDivision div = Integer::Division(r.signedIntegerNumerator(), r.integerDenominator()); assert(!div.quotient.isOverflow()); - Expression result = Rational(div.quotient); + Expression result = Rational::Builder(div.quotient); replaceWithInPlace(result); return result; } diff --git a/poincare/src/floor_layout.cpp b/poincare/src/floor_layout.cpp new file mode 100644 index 000000000..d0c04a6dc --- /dev/null +++ b/poincare/src/floor_layout.cpp @@ -0,0 +1,12 @@ +#include + +namespace Poincare { + +FloorLayout FloorLayout::Builder(Layout child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(FloorLayoutNode)); + FloorLayoutNode * node = new (bufferNode) FloorLayoutNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + +} diff --git a/poincare/src/frac_part.cpp b/poincare/src/frac_part.cpp index 1e1702760..20da772b0 100644 --- a/poincare/src/frac_part.cpp +++ b/poincare/src/frac_part.cpp @@ -28,7 +28,14 @@ Complex FracPartNode::computeOnComplex(const std::complex c, Preferences:: if (c.imag() != 0) { return Complex::Undefined(); } - return Complex(c.real()-std::floor(c.real())); + return Complex::Builder(c.real()-std::floor(c.real())); +} + +FracPart FracPart::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(FracPartNode)); + FracPartNode * node = new (bufferNode) FracPartNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); } Expression FracPart::shallowReduce() { @@ -51,7 +58,7 @@ Expression FracPart::shallowReduce() { IntegerDivision div = Integer::Division(r.signedIntegerNumerator(), r.integerDenominator()); assert(!div.remainder.isOverflow()); Integer rDenominator = r.integerDenominator(); - Expression result = Rational(div.remainder, rDenominator); + Expression result = Rational::Builder(div.remainder, rDenominator); replaceWithInPlace(result); return result; } diff --git a/poincare/src/fraction_layout.cpp b/poincare/src/fraction_layout.cpp index f18e88600..d9e15d9bd 100644 --- a/poincare/src/fraction_layout.cpp +++ b/poincare/src/fraction_layout.cpp @@ -95,7 +95,7 @@ void FractionLayoutNode::deleteBeforeCursor(LayoutCursor * cursor) { if (numeratorLayout()->isEmpty() && denominatorLayout()->isEmpty()) { /* Case: Numerator and denominator are empty. Move the cursor and replace * the fraction with an empty layout. */ - thisRef.replaceWith(EmptyLayout(), cursor); + thisRef.replaceWith(EmptyLayout::Builder(), cursor); // WARNING: Do no use "this" afterwards return; } @@ -216,4 +216,11 @@ void FractionLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expressionCo ctx->fillRect(KDRect(p.x()+Metric::FractionAndConjugateHorizontalMargin, fractionLineY, layoutSize().width()-2*Metric::FractionAndConjugateHorizontalMargin, k_fractionLineHeight), expressionColor); } -} \ No newline at end of file +FractionLayout FractionLayout::Builder(Layout numerator, Layout denominator) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(FractionLayoutNode)); + FractionLayoutNode * node = new (bufferNode) FractionLayoutNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(numerator, denominator).array(), 2); + return static_cast(h); +} + +} diff --git a/poincare/src/function.cpp b/poincare/src/function.cpp index 1eada76cb..caae12cc4 100644 --- a/poincare/src/function.cpp +++ b/poincare/src/function.cpp @@ -9,6 +9,10 @@ namespace Poincare { +FunctionNode::FunctionNode(const char * newName, int length) : SymbolAbstractNode() { + strlcpy(const_cast(name()), newName, length+1); +} + bool FunctionNode::isReal(Context & context) const { Function f(this); return SymbolAbstract::isReal(f, context); @@ -88,10 +92,13 @@ Evaluation FunctionNode::templatedApproximate(Context& context, Preferences:: return e.node()->approximate(T(), context, complexFormat, angleUnit); } -Function::Function(const char * name, size_t length) : - Function(TreePool::sharedPool()->createTreeNode(SymbolAbstract::AlignedNodeSize(length, sizeof(FunctionNode)))) -{ - static_cast(Expression::node())->setName(name, length); +Function Function::Builder(const char * name, size_t length, Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(SymbolAbstract::AlignedNodeSize(length, sizeof(FunctionNode))); + FunctionNode * node = new (bufferNode) FunctionNode(name, length); + Expression * childPointer = child.isUninitialized() ? nullptr : &child; + int numberOfChild = child.isUninitialized() ? 0 : 1; + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, childPointer, numberOfChild); + return static_cast(h); } Expression Function::replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) { @@ -100,7 +107,7 @@ Expression Function::replaceSymbolWithExpression(const SymbolAbstract & symbol, if (symbol.type() == ExpressionNode::Type::Function && strcmp(name(), symbol.name()) == 0) { Expression value = expression.clone(); // Replace the unknown in the new expression by the function's child - Symbol xSymbol = Symbol(Symbol::SpecialSymbols::UnknownX); + Symbol xSymbol = Symbol::Builder(Symbol::SpecialSymbols::UnknownX); Expression xValue = childAtIndex(0); value = value.replaceSymbolWithExpression(xSymbol, xValue); Expression p = parent(); @@ -128,7 +135,7 @@ Expression Function::shallowReplaceReplaceableSymbols(Context & context) { if (e.isUninitialized()) { return *this; } - e.replaceSymbolWithExpression(Symbol(Symbol::SpecialSymbols::UnknownX), childAtIndex(0)); + e.replaceSymbolWithExpression(Symbol::Builder(Symbol::SpecialSymbols::UnknownX), childAtIndex(0)); replaceWithInPlace(e); return e; } @@ -136,7 +143,7 @@ Expression Function::shallowReplaceReplaceableSymbols(Context & context) { // TODO: should we avoid replacing unknown X in-place but use a context instead? #if 0 VariableContext Function::unknownXContext(Context & parentContext) const { - Symbol unknownXSymbol(Symbol::SpecialSymbols::UnknownX); + Symbol unknownXSymbol = Symbol::Builder(Symbol::SpecialSymbols::UnknownX); Expression child = childAtIndex(0); const char x[] = {Symbol::SpecialSymbols::UnknownX, 0}; /* COMMENT */ diff --git a/poincare/src/great_common_divisor.cpp b/poincare/src/great_common_divisor.cpp index 3697690de..b07b8242f 100644 --- a/poincare/src/great_common_divisor.cpp +++ b/poincare/src/great_common_divisor.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -45,7 +46,14 @@ Evaluation GreatCommonDivisorNode::templatedApproximate(Context& context, Pre a = b; b = r; } - return Complex(std::round((T)a)); + return Complex::Builder(std::round((T)a)); +} + +GreatCommonDivisor GreatCommonDivisor::Builder(Expression child0, Expression child1) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(GreatCommonDivisorNode)); + GreatCommonDivisorNode * node = new (bufferNode) GreatCommonDivisorNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(child0, child1).array(), 2); + return static_cast(h); } Expression GreatCommonDivisor::shallowReduce() { @@ -59,13 +67,13 @@ Expression GreatCommonDivisor::shallowReduce() { Expression c1 = childAtIndex(1); #if MATRIX_EXACT_REDUCING if (c0.type() == ExpressionNode::Type::Matrix || c1.type() == ExpressionNode::Type::Matrix) { - return Undefined(); + return Undefined::Builder(); } #endif if (c0.type() == ExpressionNode::Type::Rational) { Rational r0 = static_cast(c0); if (!r0.integerDenominator().isOne()) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -73,7 +81,7 @@ Expression GreatCommonDivisor::shallowReduce() { if (c1.type() == ExpressionNode::Type::Rational) { Rational r1 = static_cast(c1); if (!r1.integerDenominator().isOne()) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -88,7 +96,7 @@ Expression GreatCommonDivisor::shallowReduce() { Integer b = r1.signedIntegerNumerator(); Integer gcd = Arithmetic::GCD(a, b); assert(!gcd.isOverflow()); - Expression result = Rational(gcd); + Expression result = Rational::Builder(gcd); replaceWithInPlace(result); return result; } diff --git a/poincare/src/grid_layout.cpp b/poincare/src/grid_layout.cpp index f10bde101..e96115515 100644 --- a/poincare/src/grid_layout.cpp +++ b/poincare/src/grid_layout.cpp @@ -103,7 +103,7 @@ void GridLayoutNode::addEmptyRow(EmptyLayoutNode::Color color) { int previousRowCount = m_numberOfRows; for (int i = 0; i < columnsCount; i++) { thisRef.addChildAtIndex( - EmptyLayout(color), + EmptyLayout::Builder(color), previousNumberOfChildren, previousNumberOfChildren + i, nullptr); @@ -119,7 +119,7 @@ void GridLayoutNode::addEmptyColumn(EmptyLayoutNode::Color color) { int futureColumnsCount = m_numberOfColumns + 1; for (int i = 0; i < rowsCount; i++) { thisRef.addChildAtIndex( - EmptyLayout(color), + EmptyLayout::Builder(color), i*futureColumnsCount + futureColumnsCount-1, previousNumberOfChildren + i, nullptr); @@ -268,4 +268,11 @@ void GridLayout::setDimensions(int rows, int columns) { setNumberOfColumns(columns); } +GridLayout GridLayout::Builder() { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(GridLayoutNode)); + GridLayoutNode * node = new (bufferNode) GridLayoutNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); +} + } diff --git a/poincare/src/horizontal_layout.cpp b/poincare/src/horizontal_layout.cpp index 871ff5af3..8ebb7dd9f 100644 --- a/poincare/src/horizontal_layout.cpp +++ b/poincare/src/horizontal_layout.cpp @@ -258,7 +258,7 @@ void HorizontalLayoutNode::didRemoveChildAtIndex(int index, LayoutCursor * curso * sibling (e.g. a VerticalOffsetLayout), add an empty layout at index 0 */ if (!force && index == 0 && numberOfChildren() > 0 && childAtIndex(0)->mustHaveLeftSibling()) { - Layout(this).addChildAtIndex(EmptyLayout(), 0, numberOfChildren(), cursor); + Layout(this).addChildAtIndex(EmptyLayout::Builder(), 0, numberOfChildren(), cursor); } } @@ -353,6 +353,13 @@ bool HorizontalLayoutNode::willReplaceChild(LayoutNode * oldChild, LayoutNode * // HorizontalLayout +HorizontalLayout HorizontalLayout::Builder() { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(HorizontalLayoutNode)); + HorizontalLayoutNode * node = new (bufferNode) HorizontalLayoutNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); +} + void HorizontalLayout::addOrMergeChildAtIndex(Layout l, int index, bool removeEmptyChildren, LayoutCursor * cursor) { if (l.isHorizontal()) { mergeChildrenAtIndex(HorizontalLayout(static_cast(l.node())), index, removeEmptyChildren, cursor); diff --git a/poincare/src/hyperbolic_arc_cosine.cpp b/poincare/src/hyperbolic_arc_cosine.cpp index 189059533..59f74b32c 100644 --- a/poincare/src/hyperbolic_arc_cosine.cpp +++ b/poincare/src/hyperbolic_arc_cosine.cpp @@ -23,7 +23,14 @@ Complex HyperbolicArcCosineNode::computeOnComplex(const std::complex c, Pr * on this cut. We followed the convention chosen by the lib c++ of llvm on * ]-inf+0i, 1+0i] (warning: atanh takes the other side of the cut values on * ]-inf-0i, 1-0i[).*/ - return Complex(Trigonometry::RoundToMeaningfulDigits(result, c)); + return Complex::Builder(Trigonometry::RoundToMeaningfulDigits(result, c)); +} + +HyperbolicArcCosine HyperbolicArcCosine::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(HyperbolicArcCosineNode)); + HyperbolicArcCosineNode * node = new (bufferNode) HyperbolicArcCosineNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); } template Complex Poincare::HyperbolicArcCosineNode::computeOnComplex(std::complex, Preferences::ComplexFormat, Preferences::AngleUnit); diff --git a/poincare/src/hyperbolic_arc_sine.cpp b/poincare/src/hyperbolic_arc_sine.cpp index c736f6c97..38fba0d13 100644 --- a/poincare/src/hyperbolic_arc_sine.cpp +++ b/poincare/src/hyperbolic_arc_sine.cpp @@ -26,7 +26,14 @@ Complex HyperbolicArcSineNode::computeOnComplex(const std::complex c, Pref if (c.real() == 0 && c.imag() < 1) { result.real(-result.real()); // other side of the cut } - return Complex(Trigonometry::RoundToMeaningfulDigits(result, c)); + return Complex::Builder(Trigonometry::RoundToMeaningfulDigits(result, c)); +} + +HyperbolicArcSine HyperbolicArcSine::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(HyperbolicArcSineNode)); + HyperbolicArcSineNode * node = new (bufferNode) HyperbolicArcSineNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); } template Complex Poincare::HyperbolicArcSineNode::computeOnComplex(std::complex, Preferences::ComplexFormat, Preferences::AngleUnit); diff --git a/poincare/src/hyperbolic_arc_tangent.cpp b/poincare/src/hyperbolic_arc_tangent.cpp index 11a72ddcf..83b52592b 100644 --- a/poincare/src/hyperbolic_arc_tangent.cpp +++ b/poincare/src/hyperbolic_arc_tangent.cpp @@ -27,7 +27,14 @@ Complex HyperbolicArcTangentNode::computeOnComplex(const std::complex c, P if (c.imag() == 0 && c.real() > 1) { result.imag(-result.imag()); // other side of the cut } - return Complex(Trigonometry::RoundToMeaningfulDigits(result, c)); + return Complex::Builder(Trigonometry::RoundToMeaningfulDigits(result, c)); +} + +HyperbolicArcTangent HyperbolicArcTangent::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(HyperbolicArcTangentNode)); + HyperbolicArcTangentNode * node = new (bufferNode) HyperbolicArcTangentNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); } template Complex Poincare::HyperbolicArcTangentNode::computeOnComplex(std::complex, Preferences::ComplexFormat, Preferences::AngleUnit); diff --git a/poincare/src/hyperbolic_cosine.cpp b/poincare/src/hyperbolic_cosine.cpp index bbd76e355..cfa001d4a 100644 --- a/poincare/src/hyperbolic_cosine.cpp +++ b/poincare/src/hyperbolic_cosine.cpp @@ -15,7 +15,14 @@ int HyperbolicCosineNode::serialize(char * buffer, int bufferSize, Preferences:: template Complex HyperbolicCosineNode::computeOnComplex(const std::complex c, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) { - return Complex(Trigonometry::RoundToMeaningfulDigits(std::cosh(c), c)); + return Complex::Builder(Trigonometry::RoundToMeaningfulDigits(std::cosh(c), c)); +} + +HyperbolicCosine HyperbolicCosine::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(HyperbolicCosineNode)); + HyperbolicCosineNode * node = new (bufferNode) HyperbolicCosineNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); } template Complex Poincare::HyperbolicCosineNode::computeOnComplex(std::complex, Preferences::ComplexFormat, Preferences::AngleUnit); diff --git a/poincare/src/hyperbolic_sine.cpp b/poincare/src/hyperbolic_sine.cpp index 5b1534c73..ef3064d2d 100644 --- a/poincare/src/hyperbolic_sine.cpp +++ b/poincare/src/hyperbolic_sine.cpp @@ -15,7 +15,14 @@ int HyperbolicSineNode::serialize(char * buffer, int bufferSize, Preferences::Pr template Complex HyperbolicSineNode::computeOnComplex(const std::complex c, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) { - return Complex(Trigonometry::RoundToMeaningfulDigits(std::sinh(c), c)); + return Complex::Builder(Trigonometry::RoundToMeaningfulDigits(std::sinh(c), c)); +} + +HyperbolicSine HyperbolicSine::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(HyperbolicSineNode)); + HyperbolicSineNode * node = new (bufferNode) HyperbolicSineNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); } template Complex Poincare::HyperbolicSineNode::computeOnComplex(std::complex, Preferences::ComplexFormat, Preferences::AngleUnit); diff --git a/poincare/src/hyperbolic_tangent.cpp b/poincare/src/hyperbolic_tangent.cpp index 89f0bab4b..2f7b3cec8 100644 --- a/poincare/src/hyperbolic_tangent.cpp +++ b/poincare/src/hyperbolic_tangent.cpp @@ -15,7 +15,14 @@ int HyperbolicTangentNode::serialize(char * buffer, int bufferSize, Preferences: template Complex HyperbolicTangentNode::computeOnComplex(const std::complex c, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) { - return Complex(Trigonometry::RoundToMeaningfulDigits(std::tanh(c), c)); + return Complex::Builder(Trigonometry::RoundToMeaningfulDigits(std::tanh(c), c)); +} + +HyperbolicTangent HyperbolicTangent::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(HyperbolicTangentNode)); + HyperbolicTangentNode * node = new (bufferNode) HyperbolicTangentNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); } template Complex Poincare::HyperbolicTangentNode::computeOnComplex(std::complex, Preferences::ComplexFormat, Preferences::AngleUnit); diff --git a/poincare/src/imaginary_part.cpp b/poincare/src/imaginary_part.cpp index 7667e535b..439900869 100644 --- a/poincare/src/imaginary_part.cpp +++ b/poincare/src/imaginary_part.cpp @@ -24,6 +24,13 @@ Expression ImaginaryPartNode::shallowReduce(Context & context, Preferences::Comp return ImaginaryPart(this).shallowReduce(context, complexFormat, angleUnit, target); } +ImaginaryPart ImaginaryPart::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(ImaginaryPartNode)); + ImaginaryPartNode * node = new (bufferNode) ImaginaryPartNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + Expression ImaginaryPart::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { { Expression e = Expression::defaultShallowReduce(); @@ -38,7 +45,7 @@ Expression ImaginaryPart::shallowReduce(Context & context, Preferences::ComplexF } #endif if (c.isReal(context)) { - Expression result = Rational(0); + Expression result = Rational::Builder(0); replaceWithInPlace(result); return result; } diff --git a/poincare/src/infinity.cpp b/poincare/src/infinity.cpp index a862b81db..71eb0287b 100644 --- a/poincare/src/infinity.cpp +++ b/poincare/src/infinity.cpp @@ -28,12 +28,19 @@ int InfinityNode::serialize(char * buffer, int bufferSize, Preferences::PrintFlo } template Evaluation InfinityNode::templatedApproximate() const { - return Complex(m_negative ? -INFINITY : INFINITY); + return Complex::Builder(m_negative ? -INFINITY : INFINITY); +} + +Infinity Infinity::Builder(bool negative) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(InfinityNode)); + InfinityNode * node = new (bufferNode) InfinityNode(negative); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); } Expression Infinity::setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { assert(s == ExpressionNode::Sign::Positive || s == ExpressionNode::Sign::Negative); - Expression result = Infinity(s == ExpressionNode::Sign::Negative); + Expression result = Infinity::Builder(s == ExpressionNode::Sign::Negative); replaceWithInPlace(result); return result; } diff --git a/poincare/src/integer.cpp b/poincare/src/integer.cpp index 361ce2955..675bf0b44 100644 --- a/poincare/src/integer.cpp +++ b/poincare/src/integer.cpp @@ -45,14 +45,10 @@ static inline int8_t sign(bool negative) { return 1 - 2*(int8_t)negative; } -void IntegerNode::initToMatchSize(size_t goalSize) { - assert(goalSize != sizeof(IntegerNode)); - int digitsSize = goalSize - sizeof(IntegerNode); - assert(digitsSize%sizeof(native_uint_t) == 0); - /* We are initing the Integer to match a specific size. The built integer - * is dummy. */ - m_numberOfDigits = digitsSize/sizeof(native_uint_t); - assert(size() == goalSize); +IntegerNode::IntegerNode(const native_uint_t * digits, uint8_t numberOfDigits) : + m_numberOfDigits(numberOfDigits) +{ + memcpy(m_digits, digits, numberOfDigits*sizeof(native_uint_t)); } static size_t IntegerSize(uint8_t numberOfDigits) { @@ -87,11 +83,6 @@ void IntegerNode::log(std::ostream & stream) const { #endif -void IntegerNode::setDigits(const native_uint_t * digits, uint8_t numberOfDigits) { - m_numberOfDigits = numberOfDigits; - memcpy(m_digits, digits, numberOfDigits*sizeof(native_uint_t)); -} - // Constructor Integer Integer::BuildInteger(native_uint_t * digits, uint16_t numberOfDigits, bool negative, bool enableOverflow) { @@ -109,11 +100,17 @@ Integer Integer::BuildInteger(native_uint_t * digits, uint16_t numberOfDigits, b } // Private constructor -Integer::Integer(native_uint_t * digits, uint16_t numberOfDigits, bool negative) : - TreeHandle(TreePool::sharedPool()->createTreeNode(IntegerSize(numberOfDigits))), - m_negative(negative) -{ - node()->setDigits(digits, numberOfDigits); + +Integer::Integer(native_uint_t * digits, uint16_t numberOfDigits, bool negative) { + void * bufferNode = TreePool::sharedPool()->alloc(IntegerSize(numberOfDigits)); + IntegerNode * node = new (bufferNode) IntegerNode(digits, numberOfDigits); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + /* Integer is a TreeHandle that keeps an extra integer. We cannot just cast + * the TreeHandle in Integer, we have to build a new Integer. To do so, we + * pilfer the TreeHandle identifier. We thus have to increment the node + * reference counter to prevent its destruction when we leave this scope. */ + node->retain(); + new (this) Integer(h.identifier(), negative); } Integer::Integer(native_int_t i) : TreeHandle(TreeNode::NoNodeIdentifier) { diff --git a/poincare/src/integral.cpp b/poincare/src/integral.cpp index 00d64baad..91816bb9b 100644 --- a/poincare/src/integral.cpp +++ b/poincare/src/integral.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -62,7 +63,7 @@ Evaluation IntegralNode::templatedApproximate(Context & context, Preferences: #else T result = adaptiveQuadrature(a, b, 0.1, k_maxNumberOfIterations, context, complexFormat, angleUnit); #endif - return Complex(result); + return Complex::Builder(result); } template @@ -209,6 +210,13 @@ T IntegralNode::adaptiveQuadrature(T a, T b, T eps, int numberOfIterations, Cont } #endif +Integral Integral::Builder(Expression child0, Symbol child1, Expression child2, Expression child3) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(IntegralNode)); + IntegralNode * node = new (bufferNode) IntegralNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(child0, child1, child2, child3).array(), 4); + return static_cast(h); +} + Expression Integral::shallowReduce() { { Expression e = Expression::defaultShallowReduce(); @@ -222,7 +230,7 @@ Expression Integral::shallowReduce() { || childAtIndex(2).type() == ExpressionNode::Type::Matrix || childAtIndex(3).type() == ExpressionNode::Type::Matrix) { - return Undefined(); + return Undefined::Builder(); } #endif return *this; diff --git a/poincare/src/integral_layout.cpp b/poincare/src/integral_layout.cpp index b53035fa6..43e366540 100644 --- a/poincare/src/integral_layout.cpp +++ b/poincare/src/integral_layout.cpp @@ -247,4 +247,11 @@ void IntegralLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expressionCo ctx->drawString("d", dPosition, k_font, expressionColor, backgroundColor); } +IntegralLayout IntegralLayout::Builder(Layout integrand, Layout differential, Layout lowerBound, Layout upperBound) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(IntegralLayoutNode)); + IntegralLayoutNode * node = new (bufferNode) IntegralLayoutNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(integrand, differential, lowerBound, upperBound).array(), 4); + return static_cast(h); +} + } diff --git a/poincare/src/layout.cpp b/poincare/src/layout.cpp index da2c66c5e..103f5fa6d 100644 --- a/poincare/src/layout.cpp +++ b/poincare/src/layout.cpp @@ -82,7 +82,7 @@ void Layout::replaceChild(Layout oldChild, Layout newChild, LayoutCursor * curso } void Layout::replaceChildWithEmpty(Layout oldChild, LayoutCursor * cursor) { - replaceChild(oldChild, EmptyLayout(), cursor); + replaceChild(oldChild, EmptyLayout::Builder(), cursor); } void Layout::replaceWith(Layout newChild, LayoutCursor * cursor) { diff --git a/poincare/src/layout_cursor.cpp b/poincare/src/layout_cursor.cpp index 22a7915b4..07b205b4c 100644 --- a/poincare/src/layout_cursor.cpp +++ b/poincare/src/layout_cursor.cpp @@ -73,9 +73,9 @@ void LayoutCursor::move(MoveDirection direction, bool * shouldRecomputeLayout) { /* Layout modification */ void LayoutCursor::addEmptyExponentialLayout() { - EmptyLayout emptyLayout; + EmptyLayout emptyLayout = EmptyLayout::Builder(); HorizontalLayout sibling = HorizontalLayout::Builder( - CharLayout(Ion::Charset::Exponential), + CharLayout::Builder(Ion::Charset::Exponential), VerticalOffsetLayout::Builder(emptyLayout, VerticalOffsetLayoutNode::Type::Superscript)); m_layout.addSibling(this, sibling, false); m_layout = emptyLayout; @@ -83,17 +83,17 @@ void LayoutCursor::addEmptyExponentialLayout() { void LayoutCursor::addEmptyMatrixLayout() { MatrixLayout matrixLayout = MatrixLayout::Builder( - EmptyLayout(EmptyLayoutNode::Color::Yellow), - EmptyLayout(EmptyLayoutNode::Color::Grey), - EmptyLayout(EmptyLayoutNode::Color::Grey), - EmptyLayout(EmptyLayoutNode::Color::Grey)); + EmptyLayout::Builder(EmptyLayoutNode::Color::Yellow), + EmptyLayout::Builder(EmptyLayoutNode::Color::Grey), + EmptyLayout::Builder(EmptyLayoutNode::Color::Grey), + EmptyLayout::Builder(EmptyLayoutNode::Color::Grey)); m_layout.addSibling(this, matrixLayout, false); m_layout = matrixLayout.childAtIndex(0); m_position = Position::Right; } void LayoutCursor::addEmptySquareRootLayout() { - HorizontalLayout child1 = HorizontalLayout::Builder(EmptyLayout()); + HorizontalLayout child1 = HorizontalLayout::Builder(EmptyLayout::Builder()); NthRootLayout newChild = NthRootLayout::Builder(child1); m_layout.addSibling(this, newChild, false); m_layout = newChild.childAtIndex(0); @@ -101,22 +101,22 @@ void LayoutCursor::addEmptySquareRootLayout() { } void LayoutCursor::addEmptyPowerLayout() { - VerticalOffsetLayout offsetLayout = VerticalOffsetLayout::Builder(EmptyLayout(), VerticalOffsetLayoutNode::Type::Superscript); + VerticalOffsetLayout offsetLayout = VerticalOffsetLayout::Builder(EmptyLayout::Builder(), VerticalOffsetLayoutNode::Type::Superscript); privateAddEmptyPowerLayout(offsetLayout); m_layout = offsetLayout.childAtIndex(0); } void LayoutCursor::addEmptySquarePowerLayout() { - VerticalOffsetLayout offsetLayout = VerticalOffsetLayout::Builder(CharLayout('2'), VerticalOffsetLayoutNode::Type::Superscript); + VerticalOffsetLayout offsetLayout = VerticalOffsetLayout::Builder(CharLayout::Builder('2'), VerticalOffsetLayoutNode::Type::Superscript); privateAddEmptyPowerLayout(offsetLayout); } void LayoutCursor::addEmptyTenPowerLayout() { - EmptyLayout emptyLayout; + EmptyLayout emptyLayout = EmptyLayout::Builder(); HorizontalLayout sibling = HorizontalLayout::Builder( - CharLayout(Ion::Charset::MiddleDot), - CharLayout('1'), - CharLayout('0'), + CharLayout::Builder(Ion::Charset::MiddleDot), + CharLayout::Builder('1'), + CharLayout::Builder('0'), VerticalOffsetLayout::Builder( emptyLayout, VerticalOffsetLayoutNode::Type::Superscript)); @@ -125,15 +125,15 @@ void LayoutCursor::addEmptyTenPowerLayout() { } void LayoutCursor::addFractionLayoutAndCollapseSiblings() { - HorizontalLayout child1 = HorizontalLayout::Builder(EmptyLayout()); - HorizontalLayout child2 = HorizontalLayout::Builder(EmptyLayout()); + HorizontalLayout child1 = HorizontalLayout::Builder(EmptyLayout::Builder()); + HorizontalLayout child2 = HorizontalLayout::Builder(EmptyLayout::Builder()); FractionLayout newChild = FractionLayout::Builder(child1, child2); m_layout.addSibling(this, newChild, true); Layout(newChild.node()).collapseSiblings(this); } void LayoutCursor::addXNTCharLayout() { - m_layout.addSibling(this, CharLayout(m_layout.XNTChar()), true); + m_layout.addSibling(this, CharLayout::Builder(m_layout.XNTChar()), true); } void LayoutCursor::insertText(const char * text) { @@ -148,7 +148,7 @@ void LayoutCursor::insertText(const char * text) { continue; } if (text[i] == Ion::Charset::MultiplicationSign) { - newChild = CharLayout(Ion::Charset::MiddleDot); + newChild = CharLayout::Builder(Ion::Charset::MiddleDot); } else if (text[i] == '(') { newChild = LeftParenthesisLayout::Builder(); if (pointedChild.isUninitialized()) { @@ -167,7 +167,7 @@ void LayoutCursor::insertText(const char * text) { } #endif else { - newChild = CharLayout(text[i]); + newChild = CharLayout::Builder(text[i]); } m_layout.addSibling(this, newChild, true); } @@ -217,7 +217,7 @@ void LayoutCursor::privateAddEmptyPowerLayout(VerticalOffsetLayout v) { return; } // Else, add an empty base - EmptyLayout e = EmptyLayout(); + EmptyLayout e = EmptyLayout::Builder(); HorizontalLayout newChild = HorizontalLayout::Builder(e, v); m_layout.addSibling(this, newChild, true); } diff --git a/poincare/src/layout_helper.cpp b/poincare/src/layout_helper.cpp index 9d7c584a6..7a61da0b8 100644 --- a/poincare/src/layout_helper.cpp +++ b/poincare/src/layout_helper.cpp @@ -34,7 +34,7 @@ Layout LayoutHelper::Prefix(const Expression & expression, Preferences::PrintFlo if (numberOfChildren > 0) { args.addOrMergeChildAtIndex(expression.childAtIndex(0).createLayout(floatDisplayMode, numberOfSignificantDigits), 0, true); for (int i = 1; i < numberOfChildren; i++) { - args.addChildAtIndex(CharLayout(','), args.numberOfChildren(), args.numberOfChildren(), nullptr); + args.addChildAtIndex(CharLayout::Builder(','), args.numberOfChildren(), args.numberOfChildren(), nullptr); args.addOrMergeChildAtIndex(expression.childAtIndex(i).createLayout(floatDisplayMode, numberOfSignificantDigits), args.numberOfChildren(), true); } } @@ -57,7 +57,7 @@ HorizontalLayout LayoutHelper::String(const char * buffer, int bufferLen, const assert(bufferLen > 0); HorizontalLayout resultLayout = HorizontalLayout::Builder(); for (int i = 0; i < bufferLen; i++) { - resultLayout.addChildAtIndex(CharLayout(buffer[i], font), i, i, nullptr); + resultLayout.addChildAtIndex(CharLayout::Builder(buffer[i], font), i, i, nullptr); } return resultLayout; } diff --git a/poincare/src/least_common_multiple.cpp b/poincare/src/least_common_multiple.cpp index 0549f0a75..6096658d7 100644 --- a/poincare/src/least_common_multiple.cpp +++ b/poincare/src/least_common_multiple.cpp @@ -35,7 +35,7 @@ Evaluation LeastCommonMultipleNode::templatedApproximate(Context& context, Pr return Complex::Undefined(); } if (f1 == 0.0f || f2 == 0.0f) { - return Complex(0.0); + return Complex::Builder(0.0); } int a = (int)f2; int b = (int)f1; @@ -50,7 +50,14 @@ Evaluation LeastCommonMultipleNode::templatedApproximate(Context& context, Pr a = b; b = r; } - return Complex(product/a); + return Complex::Builder(product/a); +} + +LeastCommonMultiple LeastCommonMultiple::Builder(Expression child0, Expression child1) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(LeastCommonMultipleNode)); + LeastCommonMultipleNode * node = new (bufferNode) LeastCommonMultipleNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(child0, child1).array(), 2); + return static_cast(h); } Expression LeastCommonMultiple::shallowReduce() { @@ -64,13 +71,13 @@ Expression LeastCommonMultiple::shallowReduce() { Expression c1 = childAtIndex(1); #if MATRIX_EXACT_REDUCING if (c0.type() == Type::Matrix || c1.type() == Type::Matrix) { - return Undefined(); + return Undefined::Builder(); } #endif if (c0.type() == ExpressionNode::Type::Rational) { Rational r0 = static_cast(c0); if (!r0.integerDenominator().isOne()) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -78,7 +85,7 @@ Expression LeastCommonMultiple::shallowReduce() { if (c1.type() == ExpressionNode::Type::Rational) { Rational r1 = static_cast(c1); if (!r1.integerDenominator().isOne()) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -95,7 +102,7 @@ Expression LeastCommonMultiple::shallowReduce() { if (lcm.isOverflow()) { return *this; } - Expression result = Rational(lcm); + Expression result = Rational::Builder(lcm); replaceWithInPlace(result); return result; } diff --git a/poincare/src/left_parenthesis_layout.cpp b/poincare/src/left_parenthesis_layout.cpp index 8ddd2dea5..1ec811828 100644 --- a/poincare/src/left_parenthesis_layout.cpp +++ b/poincare/src/left_parenthesis_layout.cpp @@ -59,4 +59,11 @@ void LeftParenthesisLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expre RenderWithChildHeight(ParenthesisLayoutNode::ChildHeightGivenLayoutHeight(layoutSize().height()), ctx, p, expressionColor, backgroundColor); } +LeftParenthesisLayout LeftParenthesisLayout::Builder() { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(LeftParenthesisLayoutNode)); + LeftParenthesisLayoutNode * node = new (bufferNode) LeftParenthesisLayoutNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); +} + } diff --git a/poincare/src/left_square_bracket_layout.cpp b/poincare/src/left_square_bracket_layout.cpp index 2a8d85c92..7a64a0253 100644 --- a/poincare/src/left_square_bracket_layout.cpp +++ b/poincare/src/left_square_bracket_layout.cpp @@ -8,4 +8,11 @@ void LeftSquareBracketLayoutNode::render(KDContext * ctx, KDPoint p, KDColor exp ctx->fillRect(KDRect(p.x()+k_externWidthMargin, p.y() + childHeight(), k_bracketWidth, k_lineThickness), expressionColor); } +LeftSquareBracketLayout LeftSquareBracketLayout::Builder() { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(LeftSquareBracketLayoutNode)); + LeftSquareBracketLayoutNode * node = new (bufferNode) LeftSquareBracketLayoutNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); +} + } diff --git a/poincare/src/logarithm.cpp b/poincare/src/logarithm.cpp index 9e69d9de8..a2ed4480c 100644 --- a/poincare/src/logarithm.cpp +++ b/poincare/src/logarithm.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -82,7 +83,14 @@ template Evaluation LogarithmNode<2>::templatedApproximate(Contex std::complex nc = (static_cast&>(n)).stdComplex(); result = DivisionNode::compute(computeOnComplex(xc, complexFormat, angleUnit).stdComplex(), computeOnComplex(nc, complexFormat, angleUnit).stdComplex(), complexFormat).stdComplex(); } - return Complex(result); + return Complex::Builder(result); +} + +CommonLogarithm CommonLogarithm::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(LogarithmNode<1>)); + LogarithmNode<1> * node = new (bufferNode) LogarithmNode<1>(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); } Expression CommonLogarithm::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target){ @@ -100,11 +108,18 @@ Expression CommonLogarithm::shallowReduce(Context & context, Preferences::Comple } #endif #endif - Logarithm log = Logarithm::Builder(childAtIndex(0), Rational(10)); + Logarithm log = Logarithm::Builder(childAtIndex(0), Rational::Builder(10)); replaceWithInPlace(log); return log.shallowReduce(context, complexFormat, angleUnit, target); } +Logarithm Logarithm::Builder(Expression child0, Expression child1) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(LogarithmNode<2>)); + LogarithmNode<2> * node = new (bufferNode) LogarithmNode<2>(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(child0, child1).array(), 2); + return static_cast(h); +} + Expression Logarithm::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target){ { Expression e = Expression::defaultShallowReduce(); @@ -116,7 +131,7 @@ Expression Logarithm::shallowReduce(Context & context, Preferences::ComplexForma #if MATRIX_EXACT_REDUCING #if 0 if (c.type() == ExpressionNode::Type::Matrix || childAtIndex(1).type() == ExpressionNode::Type::Matrix) { - return Undefined(); + return Undefined::Builder(); } #endif #endif @@ -196,7 +211,7 @@ Expression Logarithm::shallowReduce(Context & context, Preferences::ComplexForma Integer b = childAtIndex(1).convert().signedIntegerNumerator(); Integer newNumerator = simplifyLogarithmIntegerBaseInteger(r.signedIntegerNumerator(), b, a, false); Integer newDenomitor = simplifyLogarithmIntegerBaseInteger(r.integerDenominator(), b, a, true); - r = Rational(newNumerator, newDenomitor); + r = Rational::Builder(newNumerator, newDenomitor); } // log(r) = a0log(p0)+a1log(p1)+... with r = p0^a0*p1^a1*... (Prime decomposition) a.addChildAtIndexInPlace(splitLogarithmInteger(r.signedIntegerNumerator(), false, context, complexFormat, angleUnit, target), a.numberOfChildren(), a.numberOfChildren()); @@ -212,26 +227,26 @@ Expression Logarithm::simpleShallowReduce(Context & context, Preferences::Comple Expression b = childAtIndex(1); // log(0,0)->Undefined if (c.type() == ExpressionNode::Type::Rational && b.type() == ExpressionNode::Type::Rational && static_cast(b).isZero() && static_cast(c).isZero()) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } // log(x,1)->Undefined if (b.type() == ExpressionNode::Type::Rational && static_cast(b).isOne()) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } bool infiniteArg = c.recursivelyMatchesInfinity(context); // log(x,x)->1 with x != inf and log(inf,inf) = undef if (c.isIdenticalTo(b)) { - Expression result = infiniteArg ? Undefined().convert() : Rational(1).convert(); + Expression result = infiniteArg ? Undefined::Builder().convert() : Rational::Builder(1).convert(); replaceWithInPlace(result); return result; } // log(x,0)->0 with x != inf and log(inf,0) = undef if (b.type() == ExpressionNode::Type::Rational && static_cast(b).isZero()) { - Expression result = infiniteArg ? Undefined().convert() : Rational(0).convert(); + Expression result = infiniteArg ? Undefined::Builder().convert() : Rational::Builder(0).convert(); replaceWithInPlace(result); return result; } @@ -243,7 +258,7 @@ Expression Logarithm::simpleShallowReduce(Context & context, Preferences::Comple bool infiniteBase = b.recursivelyMatchesInfinity(context); // Special case: log(0,inf) -> undef if (infiniteBase) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -252,16 +267,16 @@ Expression Logarithm::simpleShallowReduce(Context & context, Preferences::Comple Evaluation baseApproximation = b.node()->approximate(1.0f, context, complexFormat, angleUnit); std::complex logDenominator = std::log10(static_cast&>(baseApproximation).stdComplex()); if (logDenominator.imag() != 0.0f || logDenominator.real() == 0.0f) { - result = Undefined(); + result = Undefined::Builder(); } isNegative = logDenominator.real() > 0.0; - result = result.isUninitialized() ? Infinity(isNegative) : result; + result = result.isUninitialized() ? Infinity::Builder(isNegative) : result; replaceWithInPlace(result); return result; } // log(1) = 0; if (r.isOne()) { - Expression result = Rational(0); + Expression result = Rational::Builder(0); replaceWithInPlace(result); return result; } @@ -297,7 +312,7 @@ Integer Logarithm::simplifyLogarithmIntegerBaseInteger(Integer i, Integer & base IntegerDivision div = Integer::Division(i, base); while (!div.quotient.isOverflow() && div.remainder.isZero()) { i = div.quotient; - a.addChildAtIndexInPlace(isDenominator ? Rational(-1) : Rational(1), a.numberOfChildren(), a.numberOfChildren()); // a++ + a.addChildAtIndexInPlace(isDenominator ? Rational::Builder(-1) : Rational::Builder(1), a.numberOfChildren(), a.numberOfChildren()); // a++ div = Integer::Division(i, base); } return i; @@ -310,17 +325,17 @@ Expression Logarithm::splitLogarithmInteger(Integer i, bool isDenominator, Conte Integer coefficients[Arithmetic::k_maxNumberOfPrimeFactors]; int numberOfPrimeFactors = Arithmetic::PrimeFactorization(i, factors, coefficients, Arithmetic::k_maxNumberOfPrimeFactors); if (numberOfPrimeFactors == 0) { - return Rational(0); + return Rational::Builder(0); } if (numberOfPrimeFactors < 0) { /* We could not break i in prime factor (either it might take too many * factors or too much time). */ Expression e = clone(); - e.replaceChildAtIndexInPlace(0, Rational(i)); + e.replaceChildAtIndexInPlace(0, Rational::Builder(i)); if (!isDenominator) { return e; } - Multiplication m = Multiplication::Builder(Rational(-1), e); + Multiplication m = Multiplication::Builder(Rational::Builder(-1), e); return m; } Addition a = Addition::Builder(); @@ -329,8 +344,8 @@ Expression Logarithm::splitLogarithmInteger(Integer i, bool isDenominator, Conte coefficients[index].setNegative(true); } Logarithm e = clone().convert(); - e.replaceChildAtIndexInPlace(0, Rational(factors[index])); - Multiplication m = Multiplication::Builder(Rational(coefficients[index]), e); + e.replaceChildAtIndexInPlace(0, Rational::Builder(factors[index])); + Multiplication m = Multiplication::Builder(Rational::Builder(coefficients[index]), e); e.simpleShallowReduce(context, complexFormat, angleUnit); a.addChildAtIndexInPlace(m, a.numberOfChildren(), a.numberOfChildren()); m.shallowReduce(context, complexFormat, angleUnit, target); @@ -340,13 +355,13 @@ Expression Logarithm::splitLogarithmInteger(Integer i, bool isDenominator, Conte Expression Logarithm::shallowBeautify() { assert(numberOfChildren() == 2); - Constant e = Constant(Ion::Charset::Exponential); + Constant e = Constant::Builder(Ion::Charset::Exponential); if (childAtIndex(1).isIdenticalTo(e)) { NaperianLogarithm np = NaperianLogarithm::Builder(childAtIndex(0)); replaceWithInPlace(np); return np; } - Rational ten(10); + Rational ten = Rational::Builder(10); if (childAtIndex(1).isIdenticalTo(ten)) { CommonLogarithm l = CommonLogarithm::Builder(childAtIndex(0)); replaceWithInPlace(l); diff --git a/poincare/src/matrix.cpp b/poincare/src/matrix.cpp index 66177d840..42e0bfad8 100644 --- a/poincare/src/matrix.cpp +++ b/poincare/src/matrix.cpp @@ -79,7 +79,7 @@ int MatrixNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloat template Evaluation MatrixNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { - MatrixComplex matrix; + MatrixComplex matrix = MatrixComplex::Builder(); for (ExpressionNode * c : children()) { matrix.addChildAtIndexInPlace(c->approximate(T(), context, complexFormat, angleUnit), matrix.numberOfChildren(), matrix.numberOfChildren()); } @@ -89,6 +89,13 @@ Evaluation MatrixNode::templatedApproximate(Context& context, Preferences::Co // MATRIX +Matrix Matrix::Builder() { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(MatrixNode)); + MatrixNode * node = new (bufferNode) MatrixNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); +} + void Matrix::setDimensions(int rows, int columns) { assert(rows * columns == numberOfChildren()); setNumberOfRows(rows); @@ -180,7 +187,7 @@ Matrix Matrix::rowCanonize(Context & context, Preferences::ComplexFormat complex // No non-null coefficient in this column, skip k++; // Update determinant: det *= 0 - if (!determinant.isUninitialized()) { determinant.addChildAtIndexInPlace(Rational(0), 0, determinant.numberOfChildren()); } + if (!determinant.isUninitialized()) { determinant.addChildAtIndexInPlace(Rational::Builder(0), 0, determinant.numberOfChildren()); } } else { // Swap row h and iPivot if (iPivot != h) { @@ -188,7 +195,7 @@ Matrix Matrix::rowCanonize(Context & context, Preferences::ComplexFormat complex swapChildrenInPlace(iPivot*n+col, h*n+col); } // Update determinant: det *= -1 - if (!determinant.isUninitialized()) { determinant.addChildAtIndexInPlace(Rational(-1), 0, determinant.numberOfChildren()); } + if (!determinant.isUninitialized()) { determinant.addChildAtIndexInPlace(Rational::Builder(-1), 0, determinant.numberOfChildren()); } } /* Set to 1 M[h][k] by linear combination */ Expression divisor = matrixChild(h, k); @@ -200,7 +207,7 @@ Matrix Matrix::rowCanonize(Context & context, Preferences::ComplexFormat complex replaceChildAtIndexInPlace(h*n+j, newOpHJ); newOpHJ = newOpHJ.shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System); } - replaceChildInPlace(divisor, Rational(1)); + replaceChildInPlace(divisor, Rational::Builder(1)); /* Set to 0 all M[i][j] i != h, j > k by linear combination */ for (int i = 0; i < m; i++) { @@ -213,7 +220,7 @@ Matrix Matrix::rowCanonize(Context & context, Preferences::ComplexFormat complex newOpIJ.childAtIndex(1).shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System); newOpIJ = newOpIJ.shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::System); } - replaceChildAtIndexInPlace(i*n+k, Rational(0)); + replaceChildAtIndexInPlace(i*n+k, Rational::Builder(0)); } h++; k++; @@ -292,7 +299,7 @@ Matrix Matrix::createIdentity(int dim) { Matrix matrix(); for (int i = 0; i < dim; i++) { for (int j = 0; j < dim; j++) { - matrix.addChildAtIndexInPlace(i == j ? Rational(1) : Rational(0), i*dim+j, i*dim+j); + matrix.addChildAtIndexInPlace(i == j ? Rational::Builder(1) : Rational::Builder(0), i*dim+j, i*dim+j); } } matrix.setDimensions(dim, dim); @@ -301,7 +308,7 @@ Matrix Matrix::createIdentity(int dim) { Expression Matrix::inverse(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { if (m_numberOfRows != m_numberOfColumns) { - return Undefined(); + return Undefined::Builder(); } int dim = m_numberOfRows; /* Create the matrix inv = (A|I) with A the input matrix and I the dim identity matrix */ @@ -311,7 +318,7 @@ Expression Matrix::inverse(Context & context, Preferences::ComplexFormat complex AI.addChildAtIndexInPlace(matrixChild(i, j), i*2*dim+j, i*2*dim+j); } for (int j = dim; j < 2*dim; j++) { - AI.addChildAtIndexInPlace(j-dim == i ? Rational(1) : Rational(0), i*2*dim+j, i*2*dim+j); + AI.addChildAtIndexInPlace(j-dim == i ? Rational::Builder(1) : Rational::Builder(0), i*2*dim+j, i*2*dim+j); } } AI.setDimensions(dim, 2*dim); @@ -319,7 +326,7 @@ Expression Matrix::inverse(Context & context, Preferences::ComplexFormat complex // Check inversibility for (int i = 0; i < dim; i++) { if (AI.matrixChild(i, i)->type() != ExpressionNode::Type::Rational || !static_cast(AI.matrixChild(i, i)->node())->isOne()) { - return Undefined(); + return Undefined::Builder(); } } Matrix inverse(); diff --git a/poincare/src/matrix_complex.cpp b/poincare/src/matrix_complex.cpp index 7e7d34906..416b194ea 100644 --- a/poincare/src/matrix_complex.cpp +++ b/poincare/src/matrix_complex.cpp @@ -44,7 +44,7 @@ Expression MatrixComplexNode::complexToExpression(Preferences::ComplexFormat if (c->type() == EvaluationNode::Type::Complex) { matrix.addChildAtIndexInPlace(c->complexToExpression(complexFormat), i, i); } else { - matrix.addChildAtIndexInPlace(Undefined(), i, i); + matrix.addChildAtIndexInPlace(Undefined::Builder(), i, i); } i++; } @@ -100,7 +100,7 @@ MatrixComplex MatrixComplexNode::inverse() const { if (result == 0) { /* Intentionally swapping dimensions for inverse, although it doesn't make a * difference because it is square. */ - return MatrixComplex(operandsCopy, m_numberOfColumns, m_numberOfRows); + return MatrixComplex::Builder(operandsCopy, m_numberOfColumns, m_numberOfRows); } return MatrixComplex::Undefined(); } @@ -108,10 +108,10 @@ MatrixComplex MatrixComplexNode::inverse() const { template MatrixComplex MatrixComplexNode::transpose() const { // Intentionally swapping dimensions for transpose - MatrixComplex result; + MatrixComplex result = MatrixComplex::Builder(); for (int j = 0; j < numberOfColumns(); j++) { for (int i = 0; i < numberOfRows(); i++) { - result.addChildAtIndexInPlace(Complex(complexAtIndex(i*numberOfColumns()+j)), result.numberOfChildren(), result.numberOfChildren()); + result.addChildAtIndexInPlace(Complex::Builder(complexAtIndex(i*numberOfColumns()+j)), result.numberOfChildren(), result.numberOfChildren()); } } result.setDimensions(numberOfColumns(), numberOfRows()); @@ -121,30 +121,35 @@ MatrixComplex MatrixComplexNode::transpose() const { // MATRIX COMPLEX REFERENCE template -MatrixComplex::MatrixComplex(std::complex * operands, int numberOfRows, int numberOfColumns) : - MatrixComplex() -{ +MatrixComplex MatrixComplex::Builder(std::complex * operands, int numberOfRows, int numberOfColumns) { + MatrixComplex m = MatrixComplex::Builder(); for (int i=0; i(operands[i]), i, i); + m.addChildAtIndexInPlace(Complex::Builder(operands[i]), i, i); } - setDimensions(numberOfRows, numberOfColumns); + m.setDimensions(numberOfRows, numberOfColumns); + return m; } template -MatrixComplex::MatrixComplex() : Evaluation(TreePool::sharedPool()->createTreeNode >()) {} +MatrixComplex MatrixComplex::Builder() { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(MatrixComplexNode)); + MatrixComplexNode * node = new (bufferNode) MatrixComplexNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast &>(h); +} template MatrixComplex MatrixComplex::Undefined() { std::complex undef = std::complex(NAN, NAN); - return MatrixComplex((std::complex *)&undef, 1, 1); + return MatrixComplex::Builder((std::complex *)&undef, 1, 1); } template MatrixComplex MatrixComplex::createIdentity(int dim) { - MatrixComplex result; + MatrixComplex result = MatrixComplex::Builder(); for (int i = 0; i < dim; i++) { for (int j = 0; j < dim; j++) { - Complex c = i == j ? Complex(1.0) : Complex(0.0); + Complex c = i == j ? Complex::Builder(1.0) : Complex::Builder(0.0); result.addChildAtIndexInPlace(c, i*dim+j, i*dim+j); } } diff --git a/poincare/src/matrix_dimension.cpp b/poincare/src/matrix_dimension.cpp index d9cd3e758..24e1e273e 100644 --- a/poincare/src/matrix_dimension.cpp +++ b/poincare/src/matrix_dimension.cpp @@ -34,7 +34,14 @@ Evaluation MatrixDimensionNode::templatedApproximate(Context& context, Prefer operands[0] = std::complex(1.0); operands[1] = std::complex(1.0); } - return MatrixComplex(operands, 1, 2); + return MatrixComplex::Builder(operands, 1, 2); +} + +MatrixDimension MatrixDimension::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(MatrixDimensionNode)); + MatrixDimensionNode * node = new (bufferNode) MatrixDimensionNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); } Expression MatrixDimension::shallowReduce() { @@ -49,15 +56,15 @@ Expression MatrixDimension::shallowReduce() { if (c.type() == ExpressionNode::Type::Matrix) { Matrix m = static_cast(c); Matrix result = Matrix::Builder(); - result.addChildAtIndexInPlace(Rational(m.numberOfRows()), 0, 0); - result.addChildAtIndexInPlace(Rational(m.numberOfColumns()), 1, 1); + result.addChildAtIndexInPlace(Rational::Builder(m.numberOfRows()), 0, 0); + result.addChildAtIndexInPlace(Rational::Builder(m.numberOfColumns()), 1, 1); result.setDimensions(1, 2); return result; } if (!c.recursivelyMatches(Expression::IsMatrix)) { Matrix result = Matrix::Builder(); - result.addChildAtIndexInPlace(Rational(1), 0, 0); - result.addChildAtIndexInPlace(Rational(1), 1, 1); + result.addChildAtIndexInPlace(Rational::Builder(1), 0, 0); + result.addChildAtIndexInPlace(Rational::Builder(1), 1, 1); result.setDimensions(1, 2); return result; } @@ -65,8 +72,8 @@ Expression MatrixDimension::shallowReduce() { #else if (c.type() != ExpressionNode::Type::Matrix) { Matrix result = Matrix::Builder(); - result.addChildAtIndexInPlace(Rational(1), 0, 0); - result.addChildAtIndexInPlace(Rational(1), 1, 1); + result.addChildAtIndexInPlace(Rational::Builder(1), 0, 0); + result.addChildAtIndexInPlace(Rational::Builder(1), 1, 1); result.setDimensions(1, 2); replaceWithInPlace(result); return result; diff --git a/poincare/src/matrix_inverse.cpp b/poincare/src/matrix_inverse.cpp index 16e29a94a..d12e8164d 100644 --- a/poincare/src/matrix_inverse.cpp +++ b/poincare/src/matrix_inverse.cpp @@ -34,7 +34,7 @@ Evaluation MatrixInverseNode::templatedApproximate(Context& context, Preferen if (input.type() == EvaluationNode::Type::MatrixComplex) { inverse = static_cast&>(input).inverse(); } else if (input.type() == EvaluationNode::Type::Complex) { - inverse = Complex(std::complex(1)/(static_cast&>(input).stdComplex())); + inverse = Complex::Builder(std::complex(1)/(static_cast&>(input).stdComplex())); } if (inverse.isUninitialized()) { inverse = Complex::Undefined(); @@ -42,6 +42,13 @@ Evaluation MatrixInverseNode::templatedApproximate(Context& context, Preferen return inverse; } +MatrixInverse MatrixInverse::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(MatrixInverseNode)); + MatrixInverseNode * node = new (bufferNode) MatrixInverseNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + Expression MatrixInverse::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { { Expression e = Expression::defaultShallowReduce(); @@ -53,19 +60,19 @@ Expression MatrixInverse::shallowReduce(Context & context, Preferences::ComplexF #if MATRIX_EXACT_REDUCING #if 0 if (!c.recursivelyMatches(Expression::IsMatrix)) { - return Power::Builder(c, Rational(-1).shallowReduce(context, complexFormat, angleUnit, target); + return Power::Builder(c, Rational::Builder(-1).shallowReduce(context, complexFormat, angleUnit, target); } if (c.type() == ExpressionNode::Type::Matrix) { Matrix mat = static_cast(c); if (mat.numberOfRows() != mat.numberOfColumns()) { - return Undefined(); + return Undefined::Builder(); } } return *this; #endif #else if (c.type() != ExpressionNode::Type::Matrix) { - Expression result = Power::Builder(c, Rational(-1)); + Expression result = Power::Builder(c, Rational::Builder(-1)); replaceWithInPlace(result); result = result.shallowReduce(context, complexFormat, angleUnit, target); return result; diff --git a/poincare/src/matrix_layout.cpp b/poincare/src/matrix_layout.cpp index 32d07c60f..e184fc8f1 100644 --- a/poincare/src/matrix_layout.cpp +++ b/poincare/src/matrix_layout.cpp @@ -266,4 +266,11 @@ void MatrixLayoutNode::didReplaceChildAtIndex(int index, LayoutCursor * cursor, } } +MatrixLayout MatrixLayout::Builder() { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(MatrixLayoutNode)); + MatrixLayoutNode * node = new (bufferNode) MatrixLayoutNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); +} + } diff --git a/poincare/src/matrix_trace.cpp b/poincare/src/matrix_trace.cpp index 6fcf1a326..1ff3c58a1 100644 --- a/poincare/src/matrix_trace.cpp +++ b/poincare/src/matrix_trace.cpp @@ -28,10 +28,17 @@ int MatrixTraceNode::serialize(char * buffer, int bufferSize, Preferences::Print template Evaluation MatrixTraceNode::templatedApproximate(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Evaluation input = childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); - Complex result = Complex(input.trace()); + Complex result = Complex::Builder(input.trace()); return result; } +MatrixTrace MatrixTrace::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(MatrixTraceNode)); + MatrixTraceNode * node = new (bufferNode) MatrixTraceNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + Expression MatrixTrace::shallowReduce() { { Expression e = Expression::defaultShallowReduce(); @@ -45,10 +52,10 @@ Expression MatrixTrace::shallowReduce() { if (c.type() == ExpressionNode::Type::Matrix) { Matrix m = static_cast(c); if (m.numberOfRows() != m.numberOfColumns()) { - return Undefined(); + return Undefined::Builder(); } int n = m.numberOfRows(); - Addition a = Addition(); + Addition a = Addition::Builder(); for (int i = 0; i < n; i++) { a.addChildAtIndexInPlace(m.childAtIndex(i+n*i), i, a.numberOfChildren()); } diff --git a/poincare/src/matrix_transpose.cpp b/poincare/src/matrix_transpose.cpp index b85a71918..c7e01c7be 100644 --- a/poincare/src/matrix_transpose.cpp +++ b/poincare/src/matrix_transpose.cpp @@ -37,6 +37,13 @@ Evaluation MatrixTransposeNode::templatedApproximate(Context& context, Prefer return transpose; } +MatrixTranspose MatrixTranspose::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(MatrixTransposeNode)); + MatrixTransposeNode * node = new (bufferNode) MatrixTransposeNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + Expression MatrixTranspose::shallowReduce() { { Expression e = Expression::defaultShallowReduce(); diff --git a/poincare/src/multiplication.cpp b/poincare/src/multiplication.cpp index 7e927711f..f87398e91 100644 --- a/poincare/src/multiplication.cpp +++ b/poincare/src/multiplication.cpp @@ -52,14 +52,14 @@ MatrixComplex MultiplicationNode::computeOnMatrices(const MatrixComplex m, if (m.numberOfColumns() != n.numberOfRows()) { return MatrixComplex::Undefined(); } - MatrixComplex result; + MatrixComplex result = MatrixComplex::Builder(); for (int i = 0; i < m.numberOfRows(); i++) { for (int j = 0; j < n.numberOfColumns(); j++) { std::complex c(0.0); for (int k = 0; k < m.numberOfColumns(); k++) { c += m.complexAtIndex(i*m.numberOfColumns()+k)*n.complexAtIndex(k*n.numberOfColumns()+j); } - result.addChildAtIndexInPlace(Complex(c), i*n.numberOfColumns()+j, result.numberOfChildren()); + result.addChildAtIndexInPlace(Complex::Builder(c), i*n.numberOfColumns()+j, result.numberOfChildren()); } } result.setDimensions(m.numberOfRows(), n.numberOfColumns()); @@ -108,6 +108,21 @@ Expression MultiplicationNode::denominator(Context & context, Preferences::Compl /* Multiplication */ +Multiplication Multiplication::Builder() { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(AdditionNode)); + MultiplicationNode * node = new (bufferNode) MultiplicationNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); +} + +Multiplication Multiplication::Builder(Expression * children, size_t numberOfChildren) { + Multiplication m = Multiplication::Builder(); + for (int i = 0; i < numberOfChildren; i++) { + m.addChildAtIndexInPlace(children[i], i, i); + } + return m; +} + template void Multiplication::computeOnArrays(T * m, T * n, T * result, int mNumberOfColumns, int mNumberOfRows, int nNumberOfColumns) { for (int i = 0; i < mNumberOfRows; i++) { @@ -204,9 +219,9 @@ int Multiplication::getPolynomialCoefficients(Context & context, const char * sy } // Initialization of coefficients for (int i = 1; i <= deg; i++) { - coefficients[i] = Rational(0); + coefficients[i] = Rational::Builder(0); } - coefficients[0] = Rational(1); + coefficients[0] = Rational::Builder(1); Expression intermediateCoefficients[Expression::k_maxNumberOfPolynomialCoefficients]; // Let's note result = a(0)+a(1)*X+a(2)*X^2+a(3)*x^3+.. @@ -292,7 +307,7 @@ Expression Multiplication::privateShallowReduce(Context & context, Preferences:: int on = currentMatrix->numberOfRows(); int om = currentMatrix->numberOfColumns(); if (om != n) { - return replaceWith(new Undefined(), true); + return replaceWith(new Undefined::Builder(), true); } // Create the matrix resulting of the multiplication of the current matrix and the result matrix /* resultMatrix @@ -316,7 +331,7 @@ Expression Multiplication::privateShallowReduce(Context & context, Preferences:: * */ Expression ** newMatrixOperands = new Expression * [on*m]; for (int e = 0; e < on*m; e++) { - newMatrixOperands[e] = new Addition(); + newMatrixOperands[e] = new Addition::Builder(); int i2 = e%m; int i1 = e/m; for (int j = 0; j < n; j++) { @@ -622,10 +637,10 @@ void Multiplication::addMissingFactors(Expression factor, Context & context, Pre assert(childAtIndex(0).convert().integerDenominator().isOne()); Integer lcm = Arithmetic::LCM(static_cast(factor).unsignedIntegerNumerator(), childAtIndex(0).convert().unsignedIntegerNumerator()); if (lcm.isOverflow()) { - addChildAtIndexInPlace(Rational(static_cast(factor).unsignedIntegerNumerator()), 1, numberOfChildren()); + addChildAtIndexInPlace(Rational::Builder(static_cast(factor).unsignedIntegerNumerator()), 1, numberOfChildren()); return; } - replaceChildAtIndexInPlace(0, Rational(lcm)); + replaceChildAtIndexInPlace(0, Rational::Builder(lcm)); return; } if (factor.type() != ExpressionNode::Type::Rational) { @@ -683,7 +698,7 @@ void Multiplication::factorizeSineAndCosine(int i, int j, Context & context, Pre childAtIndex(j).shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); } else { // Replace cos(x)^q by tan(x)^(-q) - Expression newPower = Power::Builder(tan, Number::Multiplication(q, Rational(-1))); + Expression newPower = Power::Builder(tan, Number::Multiplication(q, Rational::Builder(-1))); newPower.childAtIndex(1).shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); replaceChildAtIndexInPlace(j, newPower); newPower.shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); @@ -712,7 +727,7 @@ bool Multiplication::HaveSameNonNumeralFactors(const Expression & e1, const Expr } const Expression Multiplication::CreateExponent(Expression e) { - Expression result = e.type() == ExpressionNode::Type::Power ? e.childAtIndex(1).clone() : Rational(1); + Expression result = e.type() == ExpressionNode::Type::Power ? e.childAtIndex(1).clone() : Rational::Builder(1); return result; } @@ -747,11 +762,11 @@ Expression Multiplication::mergeNegativePower(Context & context, Preferences::Co // Special case for rational p/q: if q != 1, q should be at denominator if (childAtIndex(0).type() == ExpressionNode::Type::Rational && !childAtIndex(0).convert().integerDenominator().isOne()) { Rational r = childAtIndex(0).convert(); - m.addChildAtIndexInPlace(Rational(r.integerDenominator()), 0, m.numberOfChildren()); + m.addChildAtIndexInPlace(Rational::Builder(r.integerDenominator()), 0, m.numberOfChildren()); if (r.signedIntegerNumerator().isOne()) { removeChildAtIndexInPlace(0); } else { - replaceChildAtIndexInPlace(0, Rational(r.signedIntegerNumerator())); + replaceChildAtIndexInPlace(0, Rational::Builder(r.signedIntegerNumerator())); } } int i = 0; @@ -778,7 +793,7 @@ Expression Multiplication::mergeNegativePower(Context & context, Preferences::Co return *this; } m.sortChildrenInPlace([](const ExpressionNode * e1, const ExpressionNode * e2, bool canBeInterrupted) { return ExpressionNode::SimplificationOrder(e1, e2, true, canBeInterrupted); }, true); - Power p = Power::Builder(m.squashUnaryHierarchyInPlace(), Rational(-1)); + Power p = Power::Builder(m.squashUnaryHierarchyInPlace(), Rational::Builder(-1)); addChildAtIndexInPlace(p, 0, numberOfChildren()); sortChildrenInPlace([](const ExpressionNode * e1, const ExpressionNode * e2, bool canBeInterrupted) { return ExpressionNode::SimplificationOrder(e1, e2, true, canBeInterrupted); }, true); return squashUnaryHierarchyInPlace(); diff --git a/poincare/src/naperian_logarithm.cpp b/poincare/src/naperian_logarithm.cpp index 351c359b6..520dd5f3d 100644 --- a/poincare/src/naperian_logarithm.cpp +++ b/poincare/src/naperian_logarithm.cpp @@ -22,6 +22,13 @@ Expression NaperianLogarithmNode::shallowReduce(Context & context, Preferences:: return NaperianLogarithm(this).shallowReduce(context, complexFormat, angleUnit, target); } +NaperianLogarithm NaperianLogarithm::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(NaperianLogarithmNode)); + NaperianLogarithmNode * node = new (bufferNode) NaperianLogarithmNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + Expression NaperianLogarithm::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { { Expression e = Expression::defaultShallowReduce(); @@ -34,7 +41,7 @@ Expression NaperianLogarithm::shallowReduce(Context & context, Preferences::Comp return SimplificationHelper::Map(*this, context, angleUnit); } #endif - Logarithm l = Logarithm::Builder(childAtIndex(0), Constant(Ion::Charset::Exponential)); + Logarithm l = Logarithm::Builder(childAtIndex(0), Constant::Builder(Ion::Charset::Exponential)); replaceWithInPlace(l); return l.shallowReduce(context, complexFormat, angleUnit, target); } diff --git a/poincare/src/nth_root.cpp b/poincare/src/nth_root.cpp index 5c1cac751..ecb3b2b18 100644 --- a/poincare/src/nth_root.cpp +++ b/poincare/src/nth_root.cpp @@ -54,7 +54,7 @@ Evaluation NthRootNode::templatedApproximate(Context& context, Preferences::C Complex absBasePowIndex = PowerNode::compute(absBasec, std::complex(1.0)/(indexc), complexFormat); // q odd if (-1)^q = -1 if (std::pow((T)-1.0, (T)indexc.real()) < 0.0) { - return basec.real() < 0 ? Complex(-absBasePowIndex.stdComplex()) : absBasePowIndex; + return basec.real() < 0 ? Complex::Builder(-absBasePowIndex.stdComplex()) : absBasePowIndex; } } } @@ -63,6 +63,13 @@ Evaluation NthRootNode::templatedApproximate(Context& context, Preferences::C return result; } +NthRoot NthRoot::Builder(Expression child0, Expression child1) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(NthRootNode)); + NthRootNode * node = new (bufferNode) NthRootNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(child0, child1).array(), 2); + return static_cast(h); +} + Expression NthRoot::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { { Expression e = Expression::defaultShallowReduce(); @@ -72,10 +79,10 @@ Expression NthRoot::shallowReduce(Context & context, Preferences::ComplexFormat } #if MATRIX_EXACT_REDUCING if (childAtIndex(0).type() == ExpressionNode::Type::Matrix || childAtIndex(1).type() == ExpressionNode:Type::Matrix) { - return Undefined(); + return Undefined::Builder(); } #endif - Expression invIndex = Power::Builder(childAtIndex(1), Rational(-1)); + Expression invIndex = Power::Builder(childAtIndex(1), Rational::Builder(-1)); Power p = Power::Builder(childAtIndex(0), invIndex); invIndex.shallowReduce(context, complexFormat, angleUnit, target); replaceWithInPlace(p); diff --git a/poincare/src/nth_root_layout.cpp b/poincare/src/nth_root_layout.cpp index b19ea55d2..59cab9af3 100644 --- a/poincare/src/nth_root_layout.cpp +++ b/poincare/src/nth_root_layout.cpp @@ -270,4 +270,18 @@ void NthRootLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expressionCol } } +NthRootLayout NthRootLayout::Builder(Layout child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(NthRootLayoutNode)); + NthRootLayoutNode * node = new (bufferNode) NthRootLayoutNode(false); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + +NthRootLayout NthRootLayout::Builder(Layout child, Layout index) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(NthRootLayoutNode)); + NthRootLayoutNode * node = new (bufferNode) NthRootLayoutNode(true); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(child, index).array(), 2); + return static_cast(h); +} + } diff --git a/poincare/src/number.cpp b/poincare/src/number.cpp index 16e8501db..bd5c613af 100644 --- a/poincare/src/number.cpp +++ b/poincare/src/number.cpp @@ -42,7 +42,7 @@ Number Number::ParseNumber(const char * integralPart, size_t integralLength, con if (exponentLength == 0 && decimalLenght == 0) { Integer i(integralPart, integralLength, false); if (!i.isOverflow()) { - return Rational(i); + return Rational::Builder(i); } } int exp; @@ -55,32 +55,32 @@ Number Number::ParseNumber(const char * integralPart, size_t integralLength, con // Avoid Decimal with exponent > k_maxExponentLength if (exponentLength >= Decimal::k_maxExponentLength || exp > Decimal::k_maxExponent || exp < -Decimal::k_maxExponent) { if (exp < 0) { - return Decimal(0.0); + return Decimal::Builder(0.0); } else { - return Infinity(false); + return Infinity::Builder(false); } } - return Decimal(integralPart, integralLength, decimalPart, decimalLenght, exp); + return Decimal::Builder(integralPart, integralLength, decimalPart, decimalLenght, exp); } template Number Number::DecimalNumber(T f) { if (std::isnan(f)) { - return Undefined(); + return Undefined::Builder(); } if (std::isinf(f)) { - return Infinity(f < 0.0); + return Infinity::Builder(f < 0.0); } - return Decimal(f); + return Decimal::Builder(f); } Number Number::FloatNumber(double d) { if (std::isnan(d)) { - return Undefined(); + return Undefined::Builder(); } else if (std::isinf(d)) { - return Infinity(d < 0.0); + return Infinity::Builder(d < 0.0); } else { - return Float(d); + return Float::Builder(d); } } @@ -112,7 +112,7 @@ Number Number::Power(const Number & i, const Number & j) { [](const Rational & i, const Rational & j) { if (!j.integerDenominator().isOne()) { // We return an overflown result to reach the escape case Float+Float - return Rational(Integer::Overflow(false)); + return Rational::Builder(Integer::Overflow(false)); } return Rational::IntegerPower(i, j.signedIntegerNumerator()); }, diff --git a/poincare/src/opposite.cpp b/poincare/src/opposite.cpp index 12aa72853..9d2d33613 100644 --- a/poincare/src/opposite.cpp +++ b/poincare/src/opposite.cpp @@ -41,7 +41,7 @@ bool OppositeNode::childNeedsParenthesis(const TreeNode * child) const { } Layout OppositeNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - HorizontalLayout result = HorizontalLayout::Builder(CharLayout('-')); + HorizontalLayout result = HorizontalLayout::Builder(CharLayout::Builder('-')); if (childAtIndex(0)->type() == Type::Opposite) { result.addOrMergeChildAtIndex(LayoutHelper::Parentheses(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits), false), 1, false); } else { @@ -69,6 +69,19 @@ Expression OppositeNode::shallowReduce(Context & context, Preferences::ComplexFo /* Simplification */ +Opposite Opposite::Builder() { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(OppositeNode)); + OppositeNode * node = new (bufferNode) OppositeNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); +} + +Opposite Opposite::Builder(Expression child) { + Opposite d = Opposite::Builder(); + d.replaceChildAtIndexInPlace(0, child); + return d; +} + Expression Opposite::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { Expression result = Expression::defaultShallowReduce(); if (result.isUndefined()) { @@ -77,7 +90,7 @@ Expression Opposite::shallowReduce(Context & context, Preferences::ComplexFormat Expression child = result.childAtIndex(0); #if MATRIX_EXACT_REDUCING #endif - result = Multiplication::Builder(Rational(-1), child); + result = Multiplication::Builder(Rational::Builder(-1), child); replaceWithInPlace(result); return result.shallowReduce(context, complexFormat, angleUnit, target); } diff --git a/poincare/src/parenthesis.cpp b/poincare/src/parenthesis.cpp index 4fd94f1b8..ce87f1b89 100644 --- a/poincare/src/parenthesis.cpp +++ b/poincare/src/parenthesis.cpp @@ -25,6 +25,13 @@ Evaluation ParenthesisNode::templatedApproximate(Context& context, Preference return childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); } +Parenthesis Parenthesis::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(ParenthesisNode)); + ParenthesisNode * node = new (bufferNode) ParenthesisNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + Expression Parenthesis::shallowReduce() { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { diff --git a/poincare/src/parsing/parser.cpp b/poincare/src/parsing/parser.cpp index ae1024e34..0925f4f4a 100644 --- a/poincare/src/parsing/parser.cpp +++ b/poincare/src/parsing/parser.cpp @@ -164,7 +164,7 @@ void Parser::parseEmpty(Expression & leftHandSide, Token::Type stoppingType) { m_status = Status::Error; //FIXME return; } - leftHandSide = EmptyExpression(); + leftHandSide = EmptyExpression::Builder(); } void Parser::parseMinus(Expression & leftHandSide, Token::Type stoppingType) { @@ -220,7 +220,7 @@ void Parser::parseEqual(Expression & leftHandSide, Token::Type stoppingType) { if (parseBinaryOperator(leftHandSide, rightHandSide, Token::Equal)) { /* We parse until finding a token of lesser precedence than Equal. The next * token is thus either EndOfStream or Store. */ - leftHandSide = Equal(leftHandSide, rightHandSide); + leftHandSide = Equal::Builder(leftHandSide, rightHandSide); } if (!m_nextToken.is(Token::EndOfStream)) { m_status = Status::Error; // Equal should be top-most expression in Tree @@ -323,7 +323,7 @@ bool Parser::currentTokenIsSpecialIdentifier() const { } void Parser::parseConstant(Expression & leftHandSide, Token::Type stoppingType) { - leftHandSide = Constant(m_currentToken.text()[0]); + leftHandSide = Constant::Builder(m_currentToken.text()[0]); isThereImplicitMultiplication(); } @@ -360,12 +360,12 @@ void Parser::parseSequence(Expression & leftHandSide, const char name, Token::Ty if (m_status != Status::Progress) { } else if (!popTokenIfType(rightDelimiter)) { m_status = Status::Error; // Right delimiter missing. - } else if (rank.isIdenticalTo(Symbol("n",1))) { + } else if (rank.isIdenticalTo(Symbol::Builder("n",1))) { char sym[5] = {name, '(', 'n', ')', 0}; - leftHandSide = Symbol(sym, 4); - } else if (rank.isIdenticalTo(Addition::Builder(Symbol("n",1),Rational("1")))) { + leftHandSide = Symbol::Builder(sym, 4); + } else if (rank.isIdenticalTo(Addition::Builder(Symbol::Builder("n",1),Rational::Builder("1")))) { char sym[7] = {name, '(', 'n', '+', '1', ')', 0}; - leftHandSide = Symbol(sym, 6); + leftHandSide = Symbol::Builder(sym, 6); } else { m_status = Status::Error; // Unexpected parameter. } @@ -376,11 +376,11 @@ void Parser::parseSpecialIdentifier(Expression & leftHandSide) { if (m_currentToken.compareTo(Symbol::k_ans) == 0) { leftHandSide = Symbol::Ans(); } else if (m_currentToken.compareTo(Infinity::Name()) == 0) { - leftHandSide = Infinity(false); + leftHandSide = Infinity::Builder(false); } else if (m_currentToken.compareTo(Undefined::Name()) == 0) { - leftHandSide = Undefined(); + leftHandSide = Undefined::Builder(); } else if (m_currentToken.compareTo(Unreal::Name()) == 0) { - leftHandSide = Unreal(); + leftHandSide = Unreal::Builder(); } else if (m_currentToken.compareTo("u_") == 0 || m_currentToken.compareTo("v_") == 0) { // Special case for sequences (e.g. "u_{n}") parseSequence(leftHandSide, m_currentToken.text()[0], Token::LeftBrace, Token::RightBrace); } else if (m_currentToken.compareTo("u") == 0 || m_currentToken.compareTo("v") == 0) { // Special case for sequences (e.g. "u(n)") @@ -412,7 +412,7 @@ void Parser::parseCustomIdentifier(Expression & leftHandSide, const char * name, return; } if (!popTokenIfType(Token::LeftParenthesis)) { - leftHandSide = Symbol(name, length); + leftHandSide = Symbol::Builder(name, length); return; } Expression parameter = parseCommaSeparatedList(); @@ -430,7 +430,7 @@ void Parser::parseCustomIdentifier(Expression & leftHandSide, const char * name, } else if (!popTokenIfType(Token::RightParenthesis)) { m_status = Status::Error; // Right parenthesis missing. } else { - leftHandSide = Function(name, length, parameter); + leftHandSide = Function::Builder(name, length, parameter); } } diff --git a/poincare/src/permute_coefficient.cpp b/poincare/src/permute_coefficient.cpp index 61b77a357..767295862 100644 --- a/poincare/src/permute_coefficient.cpp +++ b/poincare/src/permute_coefficient.cpp @@ -37,16 +37,23 @@ Evaluation PermuteCoefficientNode::templatedApproximate(Context& context, Pre return Complex::Undefined(); } if (k > n) { - return Complex(0.0); + return Complex::Builder(0.0); } T result = 1; for (int i = (int)n-(int)k+1; i <= (int)n; i++) { result *= i; if (std::isinf(result) || std::isnan(result)) { - return Complex(result); + return Complex::Builder(result); } } - return Complex(std::round(result)); + return Complex::Builder(std::round(result)); +} + +PermuteCoefficient PermuteCoefficient::Builder(Expression child0, Expression child1) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(PermuteCoefficientNode)); + PermuteCoefficientNode * node = new (bufferNode) PermuteCoefficientNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(child0, child1).array(), 2); + return static_cast(h); } Expression PermuteCoefficient::shallowReduce() { @@ -60,13 +67,13 @@ Expression PermuteCoefficient::shallowReduce() { Expression c1 = childAtIndex(1); #if MATRIX_EXACT_REDUCING if (c0.type() == ExpressionNode::Type::Matrix || c1.type() == ExpressionNode::Type::Matrix) { - return replaceWith(new Undefined(), true); + return replaceWith(new Undefined::Builder(), true); } #endif if (c0.type() == ExpressionNode::Type::Rational) { Rational r0 = static_cast(c0); if (!r0.integerDenominator().isOne() || r0.sign() == ExpressionNode::Sign::Negative) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -74,7 +81,7 @@ Expression PermuteCoefficient::shallowReduce() { if (c1.type() == ExpressionNode::Type::Rational) { Rational r1 = static_cast(c1); if (!r1.integerDenominator().isOne() || r1.sign() == ExpressionNode::Sign::Negative) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -88,7 +95,7 @@ Expression PermuteCoefficient::shallowReduce() { Integer n = r0.unsignedIntegerNumerator(); Integer k = r1.unsignedIntegerNumerator(); if (n.isLowerThan(k)) { - Expression result = Rational(0); + Expression result = Rational::Builder(0); replaceWithInPlace(result); return result; } @@ -104,7 +111,7 @@ Expression PermuteCoefficient::shallowReduce() { result = Integer::Multiplication(result, factor); } assert(!result.isOverflow()); // < permute(k_maxNValue, k_maxNValue-1)~10^158 - Expression rationalResult = Rational(result); + Expression rationalResult = Rational::Builder(result); replaceWithInPlace(rationalResult); return rationalResult; diff --git a/poincare/src/power.cpp b/poincare/src/power.cpp index 620dcc3e7..2384d25f9 100644 --- a/poincare/src/power.cpp +++ b/poincare/src/power.cpp @@ -123,7 +123,7 @@ Complex PowerNode::compute(const std::complex c, const std::complex d, * avoid weird results as e(i*pi) = -1+6E-17*i, we compute the argument of * the result of c^d and if arg ~ 0 [Pi], we discard the residual imaginary * part and if arg ~ Pi/2 [Pi], we discard the residual real part. */ - return Complex(ApproximationHelper::TruncateRealOrImaginaryPartAccordingToArgument(result)); + return Complex::Builder(ApproximationHelper::TruncateRealOrImaginaryPartAccordingToArgument(result)); } // Layout @@ -162,8 +162,6 @@ int PowerNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatM return SerializationHelper::Infix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, "^"); } - - // Simplify Expression PowerNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { @@ -179,7 +177,7 @@ int PowerNode::simplificationOrderGreaterType(const ExpressionNode * e, bool asc if (baseComparison != 0) { return baseComparison; } - Rational one(1); + Rational one = Rational::Builder(1); return SimplificationOrder(childAtIndex(1), one.node(), ascending, canBeInterrupted); } @@ -206,7 +204,7 @@ template MatrixComplex PowerNode::computeOnMatrixAndComplex(const if (m.numberOfRows() != m.numberOfColumns()) { return MatrixComplex::Undefined(); } - T power = Complex(d).toScalar(); + T power = Complex::Builder(d).toScalar(); if (std::isnan(power) || std::isinf(power) || power != (int)power || std::fabs(power) > k_maxApproximatePowerMatrix) { return MatrixComplex::Undefined(); } @@ -215,7 +213,7 @@ template MatrixComplex PowerNode::computeOnMatrixAndComplex(const if (inverse.isUninitialized()) { return MatrixComplex::Undefined(); } - Complex minusC = Complex(-d); + Complex minusC = Complex::Builder(-d); MatrixComplex result = PowerNode::computeOnMatrixAndComplex(inverse, minusC.stdComplex(), complexFormat); return result; } @@ -236,6 +234,13 @@ template MatrixComplex PowerNode::computeOnMatrices(const MatrixC // Power +Power Power::Builder(Expression base, Expression exponent) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(PowerNode)); + PowerNode * node = new (bufferNode) PowerNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(base, exponent).array(), 2); + return static_cast(h); +} + Expression Power::setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { assert(s == ExpressionNode::Sign::Positive); if (childAtIndex(0).sign(context) == ExpressionNode::Sign::Negative) { @@ -268,9 +273,9 @@ int Power::getPolynomialCoefficients(Context & context, const char * symbolName, int n = num.extractedInt(); if (n <= k_maxPolynomialDegree) { for (int i = 0; i < n; i++) { - coefficients[i] = Rational(0); + coefficients[i] = Rational::Builder(0); } - coefficients[n] = Rational(1); + coefficients[n] = Rational::Builder(1); return n; } } @@ -290,16 +295,16 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co #if 0 /* Step 0: get rid of matrix */ if (childAtIndex(1)->type() == ExpressionNode::Type::Matrix) { - return replaceWith(new Undefined(), true); + return replaceWith(new Undefined::Builder(), true); } if (childAtIndex(0)->type() == ExpressionNode::Type::Matrix) { Matrix * mat = static_cast(childAtIndex(0)); if (childAtIndex(1)->type() != ExpressionNode::Type::Rational || !static_cast(childAtIndex(1))->denominator().isOne()) { - return replaceWith(new Undefined(), true); + return replaceWith(new Undefined::Builder(), true); } Integer exponent = static_cast(childAtIndex(1))->numerator(); if (mat->numberOfRows() != mat->numberOfColumns()) { - return replaceWith(new Undefined(), true); + return replaceWith(new Undefined::Builder(), true); } if (exponent.isNegative()) { childAtIndex(1)->setSign(Sign::Positive, context, complexFormat, angleUnit); @@ -346,7 +351,7 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co if (b.isZero()) { // 0^0 = undef or (±inf)^0 = undef if ((childAtIndex(0).type() == ExpressionNode::Type::Rational && childAtIndex(0).convert().isZero()) || childAtIndex(0).type() == ExpressionNode::Type::Infinity) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -356,7 +361,7 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co * we replace x^0 by one. This is almost always true except when x = 0. * However, not substituting x^0 by one would prevent from simplifying * many expressions like x/x->1. */ - Expression result = Rational(1); + Expression result = Rational::Builder(1); replaceWithInPlace(result); return result; } @@ -374,20 +379,20 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co if (a.isZero()) { // 0^x with x > 0 = 0 if (childAtIndex(1).sign(&context) == ExpressionNode::Sign::Positive) { - Expression result = Rational(0); + Expression result = Rational::Builder(0); replaceWithInPlace(result); return result; } // 0^x with x < 0 = undef if (childAtIndex(1).sign(&context) == ExpressionNode::Sign::Negative) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } } // 1^x = 1 if x != ±inf if (a.isOne() && !childAtIndex(1).recursivelyMatchesInfinity(context)) { - Expression result = Rational(1); + Expression result = Rational::Builder(1); replaceWithInPlace(result); return result; } @@ -443,8 +448,8 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co if ((!letPowerAtRoot && base.isReal(context) && index.type() == ExpressionNode::Type::ComplexCartesian) || (!letPowerAtRoot && base.type() == ExpressionNode::Type::ComplexCartesian && index.isReal(context)) || (!letPowerAtRoot && base.type() == ExpressionNode::Type::ComplexCartesian && index.type() == ExpressionNode::Type::ComplexCartesian)) { - complexBase = base.type() == ExpressionNode::Type::ComplexCartesian ? static_cast(base) : ComplexCartesian::Builder(base, Rational(0)); - complexIndex = index.type() == ExpressionNode::Type::ComplexCartesian ? static_cast(index) : ComplexCartesian::Builder(index, Rational(0)); + complexBase = base.type() == ExpressionNode::Type::ComplexCartesian ? static_cast(base) : ComplexCartesian::Builder(base, Rational::Builder(0)); + complexIndex = index.type() == ExpressionNode::Type::ComplexCartesian ? static_cast(index) : ComplexCartesian::Builder(index, Rational::Builder(0)); result = complexBase.power(complexIndex, context, complexFormat, angleUnit, target); replaceWithInPlace(result); return result.shallowReduce(); @@ -464,7 +469,7 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co const Rational b = childAtIndex(1).convert(); // i^(p/q) if (childAtIndex(0).type() == ExpressionNode::Type::Constant && childAtIndex(0).convert().isIComplex()) { - Number r = Number::Multiplication(b, Rational(1, 2)); + Number r = Number::Multiplication(b, Rational::Builder(1, 2)); Expression result = CreateComplexExponent(r, context, complexFormat, angleUnit, target); replaceWithInPlace(result); return result.shallowReduce(context, complexFormat, angleUnit, target); @@ -476,13 +481,13 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co Expression result; if (childAtIndex(1).sign(&context) == ExpressionNode::Sign::Negative) { // --> 0 if x < 0 - result = Rational(0); + result = Rational::Builder(0); } else if (childAtIndex(1).sign(&context) == ExpressionNode::Sign::Positive) { // --> (±inf) if x > 0 - result = Infinity(false); + result = Infinity::Builder(false); if (childAtIndex(0).sign(&context) == ExpressionNode::Sign::Negative) { // (-inf)^x --> (-1)^x*inf - Power p(Rational(-1), childAtIndex(1)); + Power p = Power::Builder(Rational::Builder(-1), childAtIndex(1)); result = Multiplication::Builder(p, result); p.shallowReduce(context, complexFormat, angleUnit, target); } @@ -520,10 +525,10 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co if (!m0.isUninitialized()) { replaceChildAtIndexInPlace(0, m0); // m0 doest not need to be shallowReduce as makePositiveAnyNegativeNumeralFactor returns a reduced expression - Multiplication m1; + Multiplication m1 = Multiplication::Builder(); replaceWithInPlace(m1); // Multiply m1 by i complex - Constant i(Ion::Charset::IComplex); + Constant i = Constant::Builder(Ion::Charset::IComplex); m1.addChildAtIndexInPlace(i, 0, 0); i.shallowReduce(context, complexFormat, angleUnit, target); m1.addChildAtIndexInPlace(*this, 1, 1); @@ -537,7 +542,7 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co Expression i = m.childAtIndex(m.numberOfChildren()-2); static_cast(m).removeChildAtIndexInPlace(m.numberOfChildren()-2); if (angleUnit == Preferences::AngleUnit::Degree) { - m.replaceChildAtIndexInPlace(m.numberOfChildren()-1, Rational(180)); + m.replaceChildAtIndexInPlace(m.numberOfChildren()-1, Rational::Builder(180)); } Expression cos = Cosine::Builder(m); m = m.shallowReduce(context, complexFormat, angleUnit, target); @@ -612,7 +617,7 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co // (sign(a)*b*...)^r if (factor.sign(&context) == ExpressionNode::Sign::Negative) { - m.replaceChildAtIndexInPlace(i, Rational(-1)); + m.replaceChildAtIndexInPlace(i, Rational::Builder(-1)); factor = factor.setSign(ExpressionNode::Sign::Positive, &context, complexFormat, angleUnit, target); } else { m.removeChildAtIndexInPlace(i); @@ -633,7 +638,7 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co } } } - // Step 12: a^(p/q+c+...) -> Rational(a^p)*a^(1/q+c+...) with a rational and a != 0 and p, q integers + // Step 12: a^(p/q+c+...) -> Rational::Builder(a^p)*a^(1/q+c+...) with a rational and a != 0 and p, q integers if (!letPowerAtRoot && childAtIndex(0).type() == ExpressionNode::Type::Rational && !childAtIndex(0).convert().isZero() @@ -729,7 +734,7 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co } } if (nr.sign() == ExpressionNode::Sign::Negative) { - nr.replaceWithInPlace(Rational(-1)); + nr.replaceWithInPlace(Rational::Builder(-1)); return shallowReduce(context, complexFormat, angleUnit, target); } else { replaceWithInPlace(result); @@ -750,11 +755,11 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co int clippedN = n.extractedInt(); // Authorized because n < k_maxExpandedBinome < k_maxNValue Expression * x0 = childAtIndex(0)->childAtIndex(0); Expression * x1 = childAtIndex(0)->childAtIndex(1); - Addition * a = new Addition(); + Addition * a = new Addition::Builder(); for (int i = 0; i <= clippedN; i++) { - Rational * r = new Rational(static_cast(BinomialCoefficient::compute(static_cast(i), static_cast(clippedN)))); - Power * p0 = new Power::Builder(x0->clone(), new Rational(i), false); - Power * p1 = new Power::Builder(x1->clone(), new Rational(clippedN-i), false); + Rational * r = new Rational::Builder(static_cast(BinomialCoefficient::compute(static_cast(i), static_cast(clippedN)))); + Power * p0 = new Power::Builder(x0->clone(), new Rational::Builder(i), false); + Power * p1 = new Power::Builder(x1->clone(), new Rational::Builder(clippedN-i), false); const Expression * operands[3] = {r, p0, p1}; Multiplication * m = new Multiplication::Builder(operands, 3, false); p0->shallowReduce(context, complexFormat, angleUnit, target); @@ -763,7 +768,7 @@ Expression Power::shallowReduce(Context & context, Preferences::ComplexFormat co m->shallowReduce(context, complexFormat, angleUnit, target); } if (nr->sign(&context) == Sign::Negative) { - nr->replaceWith(new Rational(-1), true); + nr->replaceWith(new Rational::Builder(-1), true); childAtIndex(0)->replaceWith(a, true)->shallowReduce(context, complexFormat, angleUnit, target); return shallowReduce(context, complexFormat, angleUnit, target); } else { @@ -779,7 +784,7 @@ Expression Power::shallowBeautify(Context & context, Preferences::ComplexFormat Expression p = denominator(context, complexFormat, angleUnit); // If the denominator is initialized, the index of the power is of form -y if (!p.isUninitialized()) { - Division d = Division::Builder(Rational(1), p); + Division d = Division::Builder(Rational::Builder(1), p); p.shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); replaceWithInPlace(d); return d.shallowBeautify(context, complexFormat, angleUnit, target); @@ -793,7 +798,7 @@ Expression Power::shallowBeautify(Context & context, Preferences::ComplexFormat replaceWithInPlace(result); return result; } - Expression result = NthRoot::Builder(childAtIndex(0), Rational(index)); + Expression result = NthRoot::Builder(childAtIndex(0), Rational::Builder(index)); replaceWithInPlace(result); return result; } @@ -806,8 +811,8 @@ Expression Power::shallowBeautify(Context & context, Preferences::ComplexFormat if (target == ExpressionNode::ReductionTarget::System && childAtIndex(1).type() == ExpressionNode::Type::Rational) { Integer p = childAtIndex(1).convert().signedIntegerNumerator(); Integer q = childAtIndex(1).convert().integerDenominator(); - Expression nthRoot = q.isOne() ? childAtIndex(0) : NthRoot::Builder(childAtIndex(0), Rational(q)); - Expression result = p.isOne() ? nthRoot : Power::Builder(nthRoot, Rational(p)); + Expression nthRoot = q.isOne() ? childAtIndex(0) : NthRoot::Builder(childAtIndex(0), Rational::Builder(q)); + Expression result = p.isOne() ? nthRoot : Power::Builder(nthRoot, Rational::Builder(p)); replaceWithInPlace(result); return result; } @@ -895,7 +900,7 @@ Expression Power::CreateSimplifiedIntegerRationalPower(Integer i, Rational r, bo assert(!i.isZero()); assert(r.sign() == ExpressionNode::Sign::Positive); if (i.isOne()) { - return Rational(1); + return Rational::Builder(1); } Integer factors[Arithmetic::k_maxNumberOfPrimeFactors]; Integer coefficients[Arithmetic::k_maxNumberOfPrimeFactors]; @@ -904,7 +909,7 @@ Expression Power::CreateSimplifiedIntegerRationalPower(Integer i, Rational r, bo /* We could not break i in prime factors (it might take either too many * factors or too much time). */ Expression rClone = r.clone().setSign(isDenominator ? ExpressionNode::Sign::Negative : ExpressionNode::Sign::Positive, &context, complexFormat, angleUnit, target); - return Power::Builder(Rational(i), rClone); + return Power::Builder(Rational::Builder(i), rClone); } Integer r1(1); @@ -917,18 +922,18 @@ Expression Power::CreateSimplifiedIntegerRationalPower(Integer i, Rational r, bo } if (r2.isOverflow() || r1.isOverflow()) { // we overflow Integer at one point: we abort - return Power::Builder(Rational(i), r.clone()); + return Power::Builder(Rational::Builder(i), r.clone()); } - Rational p1 = Rational(r2); + Rational p1 = Rational::Builder(r2); Integer oneExponent = isDenominator ? Integer(-1) : Integer(1); Integer rDenominator = r.integerDenominator(); - Rational p2 = Rational(oneExponent, rDenominator); + Rational p2 = Rational::Builder(oneExponent, rDenominator); Power p = Power::Builder(p1, p2); if (r1.isEqualTo(Integer(1)) && !i.isNegative()) { return p; } Integer one(1); - Rational r3 = isDenominator ? Rational(one, r1) : Rational(r1); + Rational r3 = isDenominator ? Rational::Builder(one, r1) : Rational::Builder(r1); Multiplication m = Multiplication::Builder(); m.addChildAtIndexInPlace(r3, 0, 0); if (!r2.isOne()) { @@ -942,9 +947,9 @@ Expression Power::CreateSimplifiedIntegerRationalPower(Integer i, Rational r, bo * - has no real solution otherwise */ if (!r.unsignedIntegerNumerator().isEven()) { if (r.integerDenominator().isEven()) { - return Unreal(); + return Unreal::Builder(); } else { - m.addChildAtIndexInPlace(Rational(-1), 0, m.numberOfChildren()); + m.addChildAtIndexInPlace(Rational::Builder(-1), 0, m.numberOfChildren()); } } } else { @@ -977,12 +982,12 @@ Expression Power::removeSquareRootsFromDenominator(Context & context, Preference if (pq.isOverflow()) { return result; } - Power sqrt = Power::Builder(Rational(pq), Rational(1, 2)); + Power sqrt = Power::Builder(Rational::Builder(pq), Rational::Builder(1, 2)); Integer one(1); if (castedChild1.isHalf()) { - result = Multiplication::Builder(Rational(one, q), sqrt); + result = Multiplication::Builder(Rational::Builder(one, q), sqrt); } else { - result = Multiplication::Builder(Rational(one, p), sqrt); // We use here the assertion that p != 0 + result = Multiplication::Builder(Rational::Builder(one, p), sqrt); // We use here the assertion that p != 0 } sqrt.shallowReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); } @@ -1032,16 +1037,16 @@ Expression Power::removeSquareRootsFromDenominator(Context & context, Preference // Compute the numerator Integer pq1 = Integer::Multiplication(p1, q1); Integer pq2 = Integer::Multiplication(p2, q2); - Power sqrt1 = Power::Builder(Rational(pq1), Rational(1, 2)); - Power sqrt2 = Power::Builder(Rational(pq2), Rational(1, 2)); + Power sqrt1 = Power::Builder(Rational::Builder(pq1), Rational::Builder(1, 2)); + Power sqrt2 = Power::Builder(Rational::Builder(pq2), Rational::Builder(1, 2)); Integer factor1 = Integer::Multiplication( Integer::Multiplication(n1, d1), Integer::Multiplication(Integer::Power(d2, Integer(2)), q2)); - Multiplication m1 = Multiplication::Builder(Rational(factor1), sqrt1); + Multiplication m1 = Multiplication::Builder(Rational::Builder(factor1), sqrt1); Integer factor2 = Integer::Multiplication( Integer::Multiplication(n2, d2), Integer::Multiplication(Integer::Power(d1, Integer(2)), q1)); - Multiplication m2 = Multiplication::Builder(Rational(factor2), sqrt2); + Multiplication m2 = Multiplication::Builder(Rational::Builder(factor2), sqrt2); Expression numerator; if (denominator.isNegative()) { numerator = Subtraction::Builder(m2, m1); @@ -1054,7 +1059,7 @@ Expression Power::removeSquareRootsFromDenominator(Context & context, Preference } numerator = numerator.deepReduce(context, complexFormat, angleUnit, ExpressionNode::ReductionTarget::User); Integer one(1); - result = Multiplication::Builder(numerator, Rational(one, denominator)); + result = Multiplication::Builder(numerator, Rational::Builder(one, denominator)); } if (!result.isUninitialized()) { @@ -1123,13 +1128,13 @@ bool Power::isNthRootOfUnity() const { Expression Power::equivalentExpressionUsingStandardExpression() const { if (childAtIndex(1).type() == ExpressionNode::Type::Rational) { if (childAtIndex(1).convert().isMinusOne()) { - return Division::Builder(Rational(1), childAtIndex(0).clone()); + return Division::Builder(Rational::Builder(1), childAtIndex(0).clone()); } if (childAtIndex(1).convert().isHalf()) { return SquareRoot::Builder(childAtIndex(0).clone()); } if (childAtIndex(1).convert().isMinusHalf()) { - return Division::Builder(Rational(1), SquareRoot::Builder(childAtIndex(0).clone())); + return Division::Builder(Rational::Builder(1), SquareRoot::Builder(childAtIndex(0).clone())); } } return Expression(); @@ -1137,17 +1142,17 @@ Expression Power::equivalentExpressionUsingStandardExpression() const { Expression Power::CreateComplexExponent(const Expression & r, Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { // Returns e^(i*pi*r) - const Constant exp = Constant(Ion::Charset::Exponential); - Constant iComplex = Constant(Ion::Charset::IComplex); - const Constant pi = Constant(Ion::Charset::SmallPi); + const Constant exp = Constant::Builder(Ion::Charset::Exponential); + Constant iComplex = Constant::Builder(Ion::Charset::IComplex); + const Constant pi = Constant::Builder(Ion::Charset::SmallPi); Multiplication mExp = Multiplication::Builder(iComplex, pi, r.clone()); iComplex.shallowReduce(context, complexFormat, angleUnit, target); - Power p(exp, mExp); + Power p = Power::Builder(exp, mExp); mExp.shallowReduce(context, complexFormat, angleUnit, target); return p; #if 0 - const Constant iComplex = Constant(Ion::Charset::IComplex); - const Constant pi = Constant(Ion::Charset::SmallPi); + const Constant iComplex = Constant::Builder(Ion::Charset::IComplex); + const Constant pi = Constant::Builder(Ion::Charset::SmallPi); Expression op = Multiplication::Builder(pi, r).shallowReduce(context, complexFormat, angleUnit, false); Cosine cos = Cosine(op).shallowReduce(context, complexFormat, angleUnit, false);; Sine sin = Sine(op).shallowReduce(context, complexFormat, angleUnit, false); @@ -1183,7 +1188,7 @@ bool Power::TermIsARationalSquareRootOrRational(const Expression & e) { const Rational Power::RadicandInExpression(const Expression & e) { if (e.type() == ExpressionNode::Type::Rational) { - return Rational(1); + return Rational::Builder(1); } else if (e.type() == ExpressionNode::Type::Power) { assert(e.type() == ExpressionNode::Type::Power); assert(e.childAtIndex(0).type() == ExpressionNode::Type::Rational); @@ -1200,7 +1205,7 @@ const Rational Power::RationalFactorInExpression(const Expression & e) { if (e.type() == ExpressionNode::Type::Rational) { return static_cast(e); } else if (e.type() == ExpressionNode::Type::Power) { - return Rational(1); + return Rational::Builder(1); } else { assert(e.type() == ExpressionNode::Type::Multiplication); assert(e.childAtIndex(0).type() == ExpressionNode::Type::Rational); diff --git a/poincare/src/prediction_interval.cpp b/poincare/src/prediction_interval.cpp index fd8074ee3..7f95e0f84 100644 --- a/poincare/src/prediction_interval.cpp +++ b/poincare/src/prediction_interval.cpp @@ -43,7 +43,14 @@ Evaluation PredictionIntervalNode::templatedApproximate(Context& context, Pre std::complex operands[2]; operands[0] = std::complex(p - 1.96*std::sqrt(p*(1.0-p))/std::sqrt(n)); operands[1] = std::complex(p + 1.96*std::sqrt(p*(1.0-p))/std::sqrt(n)); - return MatrixComplex(operands, 1, 2); + return MatrixComplex::Builder(operands, 1, 2); +} + +PredictionInterval PredictionInterval::Builder(Expression child0, Expression child1) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(PredictionIntervalNode)); + PredictionIntervalNode * node = new (bufferNode) PredictionIntervalNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(child0, child1).array(), 2); + return static_cast(h); } Expression PredictionInterval::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { @@ -57,13 +64,13 @@ Expression PredictionInterval::shallowReduce(Context & context, Preferences::Com Expression c1 = childAtIndex(1); #if MATRIX_EXACT_REDUCING if (c0.type() == ExpressionNode::Type::Matrix || c1.type() == ExpressionNode::Type::Matrix) { - return Undefined(); + return Undefined::Builder(); } #endif if (c0.type() == ExpressionNode::Type::Rational) { Rational r0 = static_cast(c0); if (r0.sign() == ExpressionNode::Sign::Negative || Integer::NaturalOrder(r0.unsignedIntegerNumerator(), r0.integerDenominator()) > 0) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -71,7 +78,7 @@ Expression PredictionInterval::shallowReduce(Context & context, Preferences::Com if (c1.type() == ExpressionNode::Type::Rational) { Rational r1 = static_cast(c1); if (!r1.integerDenominator().isOne() || r1.sign() == ExpressionNode::Sign::Negative) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -82,7 +89,7 @@ Expression PredictionInterval::shallowReduce(Context & context, Preferences::Com Rational r0 = static_cast(c0); Rational r1 = static_cast(c1); if (!r1.integerDenominator().isOne() || r1.sign() == ExpressionNode::Sign::Negative || r0.sign() == ExpressionNode::Sign::Negative || Integer::NaturalOrder(r0.unsignedIntegerNumerator(), r0.integerDenominator()) > 0) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } @@ -90,15 +97,15 @@ Expression PredictionInterval::shallowReduce(Context & context, Preferences::Com // Compute numerator = r0*(1-r0) Integer factorNumerator = Integer::Subtraction(r0.integerDenominator(), r0.unsignedIntegerNumerator()); Integer factorDenominator = r0.integerDenominator(); - Rational numerator = Rational::Multiplication(r0, Rational(factorNumerator, factorDenominator)); + Rational numerator = Rational::Multiplication(r0, Rational::Builder(factorNumerator, factorDenominator)); if (numerator.numeratorOrDenominatorIsInfinity()) { return *this; } // Compute sqr = sqrt(r0*(1-r0)/r1) - Expression sqr = Power::Builder(Division::Builder(numerator, r1), Rational(1, 2)); - Expression m = Multiplication::Builder(Rational(196, 100), sqr); + Expression sqr = Power::Builder(Division::Builder(numerator, r1), Rational::Builder(1, 2)); + Expression m = Multiplication::Builder(Rational::Builder(196, 100), sqr); Matrix matrix = Matrix::Builder(); - matrix.addChildAtIndexInPlace(Addition::Builder(r0.clone(), Multiplication::Builder(Rational(-1), m.clone())), 0, 0); + matrix.addChildAtIndexInPlace(Addition::Builder(r0.clone(), Multiplication::Builder(Rational::Builder(-1), m.clone())), 0, 0); matrix.addChildAtIndexInPlace(Addition::Builder(r0.clone(), m), 1, 1); matrix.setDimensions(1, 2); replaceWithInPlace(matrix); diff --git a/poincare/src/product.cpp b/poincare/src/product.cpp index f855e9974..bb422b85d 100644 --- a/poincare/src/product.cpp +++ b/poincare/src/product.cpp @@ -31,7 +31,7 @@ Evaluation ProductNode::templatedApproximateWithNextTerm(Evaluation a, Eva if (a.type() == EvaluationNode::Type::Complex && b.type() == EvaluationNode::Type::Complex) { Complex c = static_cast&>(a); Complex d = static_cast&>(b); - return Complex(c.stdComplex()*d.stdComplex()); + return Complex::Builder(c.stdComplex()*d.stdComplex()); } if (a.type() == EvaluationNode::Type::Complex) { Complex c = static_cast &>(a); @@ -46,4 +46,11 @@ Evaluation ProductNode::templatedApproximateWithNextTerm(Evaluation a, Eva return MultiplicationNode::computeOnMatrices(m, n, complexFormat); } +Product Product::Builder(Expression child0, Symbol child1, Expression child2, Expression child3) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(ProductNode)); + ProductNode * node = new (bufferNode) ProductNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(child0, child1, child2, child3).array(), 4); + return static_cast(h); +} + } diff --git a/poincare/src/product_layout.cpp b/poincare/src/product_layout.cpp index 8be05d651..3685b81f9 100644 --- a/poincare/src/product_layout.cpp +++ b/poincare/src/product_layout.cpp @@ -30,4 +30,11 @@ void ProductLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expressionCol SequenceLayoutNode::render(ctx, p, expressionColor, backgroundColor); } +ProductLayout ProductLayout::Builder(Layout argument, Layout variable, Layout lowerB, Layout upperB) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(ProductLayoutNode)); + ProductLayoutNode * node = new (bufferNode) ProductLayoutNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(argument, variable, lowerB, upperB).array(), 4); + return static_cast(h); +} + } diff --git a/poincare/src/randint.cpp b/poincare/src/randint.cpp index 269e0a1a4..645e1ca88 100644 --- a/poincare/src/randint.cpp +++ b/poincare/src/randint.cpp @@ -34,7 +34,14 @@ template Evaluation RandintNode::templateApproximate(Context & c } T result = std::floor(Random::random()*(b+1.0-a)+a); - return Complex(result); + return Complex::Builder(result); +} + +Randint Randint::Builder(Expression child0, Expression child1) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(RandintNode)); + RandintNode * node = new (bufferNode) RandintNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(child0, child1).array(), 2); + return static_cast(h); } } diff --git a/poincare/src/random.cpp b/poincare/src/random.cpp index e31bde088..3d8e0e546 100644 --- a/poincare/src/random.cpp +++ b/poincare/src/random.cpp @@ -26,7 +26,14 @@ int RandomNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloat } template Evaluation RandomNode::templateApproximate() const { - return Complex(Random::random()); + return Complex::Builder(Random::random()); +} + +Random Random::Builder() { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(RandomNode)); + RandomNode * node = new (bufferNode) RandomNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); } Expression Random::setSign(ExpressionNode::Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { diff --git a/poincare/src/rational.cpp b/poincare/src/rational.cpp index 504aa05cf..3247d5c2d 100644 --- a/poincare/src/rational.cpp +++ b/poincare/src/rational.cpp @@ -15,10 +15,11 @@ namespace Poincare { /* Rational Node */ -void RationalNode::setDigits(const native_uint_t * numeratorDigits, uint8_t numeratorSize, const native_uint_t * denominatorDigits, uint8_t denominatorSize, bool negative) { - m_negative = negative; - m_numberOfDigitsNumerator = numeratorSize; - m_numberOfDigitsDenominator = denominatorSize; +RationalNode::RationalNode(const native_uint_t * numeratorDigits, uint8_t numeratorSize, const native_uint_t * denominatorDigits, uint8_t denominatorSize, bool negative) : + m_negative(negative), + m_numberOfDigitsNumerator(numeratorSize), + m_numberOfDigitsDenominator(denominatorSize) +{ if (numeratorDigits) { memcpy(m_digits, numeratorDigits, numeratorSize*sizeof(native_uint_t)); } @@ -27,20 +28,6 @@ void RationalNode::setDigits(const native_uint_t * numeratorDigits, uint8_t nume } } -void RationalNode::initToMatchSize(size_t goalSize) { - assert(goalSize != sizeof(RationalNode)); - int digitsSize = goalSize - sizeof(RationalNode); - assert(digitsSize%sizeof(native_uint_t) == 0); - /* We are initing the Rational to match a specific size. The built rational - * is dummy. However, we cannot assign to m_numberOfDigitsNumerator (or - * m_numberOfDigitsDenominator) values that are aboce k_maxNumberOfDigits. - * To prevent that, we evenly separe digits between numerator and denominator. */ - size_t numberOfDigits = digitsSize/sizeof(native_uint_t); - m_numberOfDigitsNumerator = numberOfDigits/2; - m_numberOfDigitsDenominator = numberOfDigits-m_numberOfDigitsNumerator; - assert(size() == goalSize); -} - Integer RationalNode::signedNumerator() const { return Integer::BuildInteger((native_uint_t *)m_digits, m_numberOfDigitsNumerator, m_negative); } @@ -163,7 +150,7 @@ Expression RationalNode::denominator(Context & context, Preferences::ComplexForm // Constructors -Rational::Rational(Integer & num, Integer & den) : Number() { +Rational Rational::Builder(Integer & num, Integer & den) { assert(!den.isZero()); if (!num.isOne() && !den.isOne()) { // Avoid computing GCD if possible @@ -172,34 +159,33 @@ Rational::Rational(Integer & num, Integer & den) : Number() { den = Integer::Division(den, gcd).quotient; } bool negative = (!num.isNegative() && den.isNegative()) || (!den.isNegative() && num.isNegative()); - new (this) Rational(num.digits(), num.numberOfDigits(), den.digits(), den.numberOfDigits(), negative); + return Rational::Builder(num.digits(), num.numberOfDigits(), den.digits(), den.numberOfDigits(), negative); } -Rational::Rational(const Integer & numerator) : Number() { +Rational Rational::Builder(const Integer & numerator) { native_uint_t one = 1; - new (this) Rational(numerator.digits(), numerator.numberOfDigits(), &one, 1, numerator.isNegative()); + return Rational::Builder(numerator.digits(), numerator.numberOfDigits(), &one, 1, numerator.isNegative()); } -Rational::Rational(native_int_t i) : Number() { +Rational Rational::Builder(native_int_t i) { native_uint_t one = 1; if (i == 0) { - new (this) Rational(nullptr, 0, &one, 1, false); - return; + return Rational::Builder(nullptr, 0, &one, 1, false); } native_uint_t absI = i < 0 ? -i : i; - new (this) Rational(&absI, 1, &one, 1, i < 0); + return Rational::Builder(&absI, 1, &one, 1, i < 0); } -Rational::Rational(native_int_t i, native_int_t j) : Number() { +Rational Rational::Builder(native_int_t i, native_int_t j) { Integer iInteger(i); Integer jInteger(j); - new (this) Rational(iInteger, jInteger); + return Rational::Builder(iInteger, jInteger); } -Rational::Rational(const char * iString, const char * jString) : Number() { +Rational Rational::Builder(const char * iString, const char * jString) { Integer iInteger(iString); Integer jInteger(jString); - new (this) Rational(iInteger, jInteger); + return Rational::Builder(iInteger, jInteger); } bool Rational::numeratorOrDenominatorIsInfinity() const { @@ -211,13 +197,13 @@ bool Rational::numeratorOrDenominatorIsInfinity() const { Rational Rational::Addition(const Rational & i, const Rational & j) { Integer newNumerator = Integer::Addition(Integer::Multiplication(i.signedIntegerNumerator(), j.integerDenominator()), Integer::Multiplication(j.signedIntegerNumerator(), i.integerDenominator())); Integer newDenominator = Integer::Multiplication(i.integerDenominator(), j.integerDenominator()); - return Rational(newNumerator, newDenominator); + return Rational::Builder(newNumerator, newDenominator); } Rational Rational::Multiplication(const Rational & i, const Rational & j) { Integer newNumerator = Integer::Multiplication(i.signedIntegerNumerator(), j.signedIntegerNumerator()); Integer newDenominator = Integer::Multiplication(i.integerDenominator(), j.integerDenominator()); - return Rational(newNumerator, newDenominator); + return Rational::Builder(newNumerator, newDenominator); } Rational Rational::IntegerPower(const Rational & i, const Integer & j) { @@ -226,15 +212,16 @@ Rational Rational::IntegerPower(const Rational & i, const Integer & j) { Integer newNumerator = Integer::Power(i.signedIntegerNumerator(), absJ); Integer newDenominator = Integer::Power(i.integerDenominator(), absJ); if (j.isNegative()) { - return Rational(newDenominator, newNumerator); + return Rational::Builder(newDenominator, newNumerator); } - return Rational(newNumerator, newDenominator); + return Rational::Builder(newNumerator, newDenominator); } -Rational::Rational(const native_uint_t * i, uint8_t numeratorSize, const native_uint_t * j, uint8_t denominatorSize, bool negative) : - Number(TreePool::sharedPool()->createTreeNode(RationalSize(numeratorSize, denominatorSize))) -{ - static_cast(node())->setDigits(i, numeratorSize, j, denominatorSize, negative); +Rational Rational::Builder(const native_uint_t * i, uint8_t numeratorSize, const native_uint_t * j, uint8_t denominatorSize, bool negative) { + void * bufferNode = TreePool::sharedPool()->alloc(RationalSize(numeratorSize, denominatorSize)); + RationalNode * node = new (bufferNode) RationalNode(i, numeratorSize, j, denominatorSize, negative); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); } Expression Rational::shallowReduce() { @@ -246,17 +233,17 @@ Expression Rational::shallowReduce() { #if 0 if (unsignedIntegerNumerator().isOverflow() && integerDenominator().isOverflow()) { assert(false); - return Undefined(); + return Undefined::Builder(); } // Turn into Infinite if the numerator is too big. if (unsignedIntegerNumerator().isOverflow()) { assert(false); - return Infinity(sign(&context) == ExpressionNode::Sign::Negative); + return Infinity::Builder(sign(&context) == ExpressionNode::Sign::Negative); } // Turn into 0 if the denominator is too big. if (integerDenominator().isOverflow()) { assert(false); - return Rational(0); + return Rational::Builder(0); } #endif assert(!numeratorOrDenominatorIsInfinity()); @@ -280,9 +267,9 @@ Expression Rational::denominator(Context & context, Preferences::ComplexFormat c return Expression(); } if (d.isOverflow()) { - return Infinity(false); + return Infinity::Builder(false); } - return Rational(d); + return Rational::Builder(d); } Expression Rational::setSign(ExpressionNode::Sign s) { diff --git a/poincare/src/real_part.cpp b/poincare/src/real_part.cpp index 4d5e58c7e..95cf8534b 100644 --- a/poincare/src/real_part.cpp +++ b/poincare/src/real_part.cpp @@ -24,6 +24,13 @@ Expression RealPartNode::shallowReduce(Context & context, Preferences::ComplexFo return RealPart(this).shallowReduce(context, complexFormat, angleUnit, target); } +RealPart RealPart::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(RealPartNode)); + RealPartNode * node = new (bufferNode) RealPartNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + Expression RealPart::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { { Expression e = Expression::defaultShallowReduce(); diff --git a/poincare/src/right_parenthesis_layout.cpp b/poincare/src/right_parenthesis_layout.cpp index d38345f20..68a267f96 100644 --- a/poincare/src/right_parenthesis_layout.cpp +++ b/poincare/src/right_parenthesis_layout.cpp @@ -59,4 +59,11 @@ void RightParenthesisLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expr RenderWithChildHeight(ParenthesisLayoutNode::ChildHeightGivenLayoutHeight(layoutSize().height()), ctx, p, expressionColor, backgroundColor); } +RightParenthesisLayout RightParenthesisLayout::Builder() { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(RightParenthesisLayoutNode)); + RightParenthesisLayoutNode * node = new (bufferNode) RightParenthesisLayoutNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); +} + } diff --git a/poincare/src/right_square_bracket_layout.cpp b/poincare/src/right_square_bracket_layout.cpp index cd1608a02..3707312fe 100644 --- a/poincare/src/right_square_bracket_layout.cpp +++ b/poincare/src/right_square_bracket_layout.cpp @@ -8,4 +8,11 @@ void RightSquareBracketLayoutNode::render(KDContext * ctx, KDPoint p, KDColor ex ctx->fillRect(KDRect(p.x()+k_widthMargin-k_bracketWidth+1, p.y() + childHeight(), k_bracketWidth, k_lineThickness), expressionColor); } +RightSquareBracketLayout RightSquareBracketLayout::Builder() { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(RightSquareBracketLayoutNode)); + RightSquareBracketLayoutNode * node = new (bufferNode) RightSquareBracketLayoutNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); +} + } diff --git a/poincare/src/round.cpp b/poincare/src/round.cpp index f0205ef19..5fc95311c 100644 --- a/poincare/src/round.cpp +++ b/poincare/src/round.cpp @@ -35,7 +35,14 @@ Evaluation RoundNode::templatedApproximate(Context& context, Preferences::Com return Complex::Undefined(); } T err = std::pow(10, std::floor(f2)); - return Complex(std::round(f1*err)/err); + return Complex::Builder(std::round(f1*err)/err); +} + +Round Round::Builder(Expression child0, Expression child1) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(RoundNode)); + RoundNode * node = new (bufferNode) RoundNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(child0, child1).array(), 2); + return static_cast(h); } Expression Round::shallowReduce() { @@ -47,7 +54,7 @@ Expression Round::shallowReduce() { } #if MATRIX_EXACT_REDUCING if (childAtIndex(0).type() == ExpressionNode::Type::Matrix || childAtIndex(1).type() == ExpressionNode::Type::Matrix) { - return Undefined(); + return Undefined::Builder(); } #endif /* We reduce only round(Rational, Rational). We do not reduce @@ -56,11 +63,11 @@ Expression Round::shallowReduce() { Rational r1 = childAtIndex(0).convert(); Rational r2 = childAtIndex(1).convert(); if (!r2.integerDenominator().isOne()) { - Expression result = Undefined(); + Expression result = Undefined::Builder(); replaceWithInPlace(result); return result; } - const Rational ten(10); + const Rational ten = Rational::Builder(10); if (Power::RationalExponentShouldNotBeReduced(ten, r2)) { return *this; } @@ -69,10 +76,10 @@ Expression Round::shallowReduce() { IntegerDivision d = Integer::Division(mult.signedIntegerNumerator(), mult.integerDenominator()); Integer rounding = d.quotient; Integer multDenominator = mult.integerDenominator(); - if (Rational::NaturalOrder(Rational(d.remainder, multDenominator), Rational(1,2)) >= 0) { + if (Rational::NaturalOrder(Rational::Builder(d.remainder, multDenominator), Rational::Builder(1,2)) >= 0) { rounding = Integer::Addition(rounding, Integer(1)); } - Rational result = Rational::Multiplication(rounding, Rational::IntegerPower(Rational(1,10), r2.signedIntegerNumerator())); + Rational result = Rational::Multiplication(Rational::Builder(rounding), Rational::IntegerPower(Rational::Builder(1,10), r2.signedIntegerNumerator())); if (result.numeratorOrDenominatorIsInfinity()) { return *this; } diff --git a/poincare/src/sequence.cpp b/poincare/src/sequence.cpp index 336a164b4..5e09b9732 100644 --- a/poincare/src/sequence.cpp +++ b/poincare/src/sequence.cpp @@ -29,7 +29,7 @@ Evaluation SequenceNode::templatedApproximate(Context& context, Preferences:: return Complex::Undefined(); } VariableContext nContext = VariableContext(static_cast(childAtIndex(1))->name(), &context); - Evaluation result = Complex((T)emptySequenceValue()); + Evaluation result = Complex::Builder((T)emptySequenceValue()); for (int i = (int)start; i <= (int)end; i++) { if (Expression::ShouldStopProcessing()) { return Complex::Undefined(); diff --git a/poincare/src/sign_function.cpp b/poincare/src/sign_function.cpp index 340beb9a8..0099b02c7 100644 --- a/poincare/src/sign_function.cpp +++ b/poincare/src/sign_function.cpp @@ -20,7 +20,7 @@ ExpressionNode::Sign SignFunctionNode::sign(Context * context) const { Expression SignFunctionNode::setSign(Sign s, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { assert(s == ExpressionNode::Sign::Positive || s == ExpressionNode::Sign::Negative); SignFunction sign(this); - Rational r(s == ExpressionNode::Sign::Positive ? 1 : -1); + Rational r = Rational::Builder(s == ExpressionNode::Sign::Positive ? 1 : -1); sign.replaceWithInPlace(r); return r; } @@ -43,12 +43,19 @@ Complex SignFunctionNode::computeOnComplex(const std::complex c, Preferenc return Complex::Undefined(); } if (c.real() == 0) { - return Complex(0.0); + return Complex::Builder(0.0); } if (c.real() < 0) { - return Complex(-1.0); + return Complex::Builder(-1.0); } - return Complex(1.0); + return Complex::Builder(1.0); +} + +SignFunction SignFunction::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(SignFunctionNode)); + SignFunctionNode * node = new (bufferNode) SignFunctionNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); } Expression SignFunction::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { @@ -63,11 +70,11 @@ Expression SignFunction::shallowReduce(Context & context, Preferences::ComplexFo return SimplificationHelper::Map(*this, context, angleUnit); } #endif - Rational resultSign(1); + Rational resultSign = Rational::Builder(1); Expression child = childAtIndex(0); ExpressionNode::Sign s = child.sign(&context); if (s == ExpressionNode::Sign::Negative) { - resultSign = Rational(-1); + resultSign = Rational::Builder(-1); } else { Evaluation childApproximated = child.node()->approximate(1.0f, context, complexFormat, angleUnit); assert(childApproximated.type() == EvaluationNode::Type::Complex); @@ -83,15 +90,15 @@ Expression SignFunction::shallowReduce(Context & context, Preferences::ComplexFo return *this; } Expression sign = *this; - Multiplication m = Multiplication::Builder(Rational(-1)); + Multiplication m = Multiplication::Builder(Rational::Builder(-1)); replaceWithInPlace(m); m.addChildAtIndexInPlace(sign, 1, 1); // sign does not need to be shallowReduced because -x = NAN --> x = NAN return m; // m does not need to be shallowReduced, -1*sign cannot be reduced } } else if (c.real() < 0) { - resultSign = Rational(-1); + resultSign = Rational::Builder(-1); } else if (c.real() == 0) { - resultSign = Rational(0); + resultSign = Rational::Builder(0); } } replaceWithInPlace(resultSign); diff --git a/poincare/src/sine.cpp b/poincare/src/sine.cpp index 9ecf57eaa..5099382d2 100644 --- a/poincare/src/sine.cpp +++ b/poincare/src/sine.cpp @@ -19,7 +19,7 @@ template Complex SineNode::computeOnComplex(const std::complex c, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) { std::complex angleInput = Trigonometry::ConvertToRadian(c, angleUnit); std::complex res = std::sin(angleInput); - return Complex(Trigonometry::RoundToMeaningfulDigits(res, angleInput)); + return Complex::Builder(Trigonometry::RoundToMeaningfulDigits(res, angleInput)); } Layout SineNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { @@ -34,6 +34,13 @@ Expression SineNode::shallowReduce(Context & context, Preferences::ComplexFormat return Sine(this).shallowReduce(context, complexFormat, angleUnit, target); } +Sine Sine::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(SineNode)); + SineNode * node = new (bufferNode) SineNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + Expression Sine::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { { Expression e = Expression::defaultShallowReduce(); diff --git a/poincare/src/square_root.cpp b/poincare/src/square_root.cpp index 8438dd663..747d48c51 100644 --- a/poincare/src/square_root.cpp +++ b/poincare/src/square_root.cpp @@ -35,13 +35,20 @@ Complex SquareRootNode::computeOnComplex(const std::complex c, Preferences * weird results as sqrt(-1) = 6E-16+i, we compute the argument of the result * of sqrt(c) and if arg ~ 0 [Pi], we discard the residual imaginary part and * if arg ~ Pi/2 [Pi], we discard the residual real part.*/ - return Complex(ApproximationHelper::TruncateRealOrImaginaryPartAccordingToArgument(result)); + return Complex::Builder(ApproximationHelper::TruncateRealOrImaginaryPartAccordingToArgument(result)); } Expression SquareRootNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { return SquareRoot(this).shallowReduce(context, complexFormat, angleUnit, target); } +SquareRoot SquareRoot::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(SquareRootNode)); + SquareRootNode * node = new (bufferNode) SquareRootNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + Expression SquareRoot::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { { Expression e = Expression::defaultShallowReduce(); @@ -54,7 +61,7 @@ Expression SquareRoot::shallowReduce(Context & context, Preferences::ComplexForm return SimplificationHelper::Map(this, context, angleUnit); } #endif - Power p = Power::Builder(childAtIndex(0), Rational(1, 2)); + Power p = Power::Builder(childAtIndex(0), Rational::Builder(1, 2)); replaceWithInPlace(p); return p.shallowReduce(context, complexFormat, angleUnit, target); } diff --git a/poincare/src/store.cpp b/poincare/src/store.cpp index 1c1bdc2f3..4eb0830b0 100644 --- a/poincare/src/store.cpp +++ b/poincare/src/store.cpp @@ -34,7 +34,7 @@ int StoreNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatM Layout StoreNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { HorizontalLayout result = HorizontalLayout::Builder(); result.addOrMergeChildAtIndex(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits), 0, false); - result.addChildAtIndex(CharLayout(Ion::Charset::Sto), result.numberOfChildren(), result.numberOfChildren(), nullptr); + result.addChildAtIndex(CharLayout::Builder(Ion::Charset::Sto), result.numberOfChildren(), result.numberOfChildren(), nullptr); result.addOrMergeChildAtIndex(childAtIndex(1)->createLayout(floatDisplayMode, numberOfSignificantDigits), result.numberOfChildren(), false); return result; } @@ -69,13 +69,20 @@ Expression Store::shallowReduce(Context & context, Preferences::ComplexFormat co return storedExpression; } +Store Store::Builder(Expression value, SymbolAbstract symbol) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(StoreNode)); + StoreNode * node = new (bufferNode) StoreNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(value, symbol).array(), 2); + return static_cast(h); +} + Expression Store::storeValueForSymbol(Context& context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { Expression finalValue; if (symbol().type() == ExpressionNode::Type::Function) { // In tata + 2 ->f(tata), replace tata with xUnknown symbol assert(symbol().childAtIndex(0).type() == ExpressionNode::Type::Symbol); Expression userDefinedUnknown = symbol().childAtIndex(0); - Symbol xUnknown = Symbol(Symbol::SpecialSymbols::UnknownX); + Symbol xUnknown = Symbol::Builder(Symbol::SpecialSymbols::UnknownX); finalValue = childAtIndex(0).replaceSymbolWithExpression(static_cast(userDefinedUnknown), xUnknown); } else { assert(symbol().type() == ExpressionNode::Type::Symbol); @@ -86,13 +93,13 @@ Expression Store::storeValueForSymbol(Context& context, Preferences::ComplexForm Expression storedExpression = context.expressionForSymbol(symbol(), true); if (storedExpression.isUninitialized()) { - return Undefined(); + return Undefined::Builder(); } if (symbol().type() == ExpressionNode::Type::Function) { // Replace the xUnknown symbol with the variable initially used assert(symbol().childAtIndex(0).type() == ExpressionNode::Type::Symbol); Expression userDefinedUnknown = symbol().childAtIndex(0); - Symbol xUnknown = Symbol(Symbol::SpecialSymbols::UnknownX); + Symbol xUnknown = Symbol::Builder(Symbol::SpecialSymbols::UnknownX); storedExpression = storedExpression.replaceSymbolWithExpression(xUnknown, static_cast(userDefinedUnknown)); } return storedExpression; diff --git a/poincare/src/subtraction.cpp b/poincare/src/subtraction.cpp index 4dabad1b0..8978925b0 100644 --- a/poincare/src/subtraction.cpp +++ b/poincare/src/subtraction.cpp @@ -44,7 +44,7 @@ int SubtractionNode::serialize(char * buffer, int bufferSize, Preferences::Print template MatrixComplex SubtractionNode::computeOnComplexAndMatrix(const std::complex c, const MatrixComplex m, Preferences::ComplexFormat complexFormat) { MatrixComplex opposite = computeOnMatrixAndComplex(m, c, complexFormat); - MatrixComplex result; + MatrixComplex result = MatrixComplex::Builder(); for (int i = 0; i < opposite.numberOfChildren(); i++) { result.addChildAtIndexInPlace(OppositeNode::compute(opposite.complexAtIndex(i), complexFormat), i, i); } @@ -56,12 +56,26 @@ Expression SubtractionNode::shallowReduce(Context & context, Preferences::Comple return Subtraction(this).shallowReduce(context, complexFormat, angleUnit, target); } +Subtraction Subtraction::Builder() { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(SubtractionNode)); + SubtractionNode * node = new (bufferNode) SubtractionNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); +} + +Subtraction Subtraction::Builder(Expression child0, Expression child1) { + Subtraction d = Subtraction::Builder(); + d.replaceChildAtIndexInPlace(0, child0); + d.replaceChildAtIndexInPlace(1, child1); + return d; +} + Expression Subtraction::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { Expression e = Expression::defaultShallowReduce(); if (e.isUndefined()) { return e; } - Expression m = Multiplication::Builder(Rational(-1), childAtIndex(1)); + Expression m = Multiplication::Builder(Rational::Builder(-1), childAtIndex(1)); Addition a = Addition::Builder(childAtIndex(0), m); m = m.shallowReduce(context, complexFormat, angleUnit, target); replaceWithInPlace(a); diff --git a/poincare/src/sum.cpp b/poincare/src/sum.cpp index ffc0620ad..e8bdeac55 100644 --- a/poincare/src/sum.cpp +++ b/poincare/src/sum.cpp @@ -31,7 +31,7 @@ Evaluation SumNode::templatedApproximateWithNextTerm(Evaluation a, Evaluat if (a.type() == EvaluationNode::Type::Complex && b.type() == EvaluationNode::Type::Complex) { Complex c = static_cast&>(a); Complex d = static_cast&>(b); - return Complex(c.stdComplex()+d.stdComplex()); + return Complex::Builder(c.stdComplex()+d.stdComplex()); } if (a.type() == EvaluationNode::Type::Complex) { Complex c = static_cast &>(a); @@ -46,4 +46,11 @@ Evaluation SumNode::templatedApproximateWithNextTerm(Evaluation a, Evaluat return AdditionNode::computeOnMatrices(m, n, complexFormat); } +Sum Sum::Builder(Expression child0, Symbol child1, Expression child2, Expression child3) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(SumNode)); + SumNode * node = new (bufferNode) SumNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(child0, child1, child2, child3).array(), 4); + return static_cast(h); +} + } diff --git a/poincare/src/sum_layout.cpp b/poincare/src/sum_layout.cpp index 9c9a079e8..1297b124a 100644 --- a/poincare/src/sum_layout.cpp +++ b/poincare/src/sum_layout.cpp @@ -45,4 +45,11 @@ void SumLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expressionColor, SequenceLayoutNode::render(ctx, p, expressionColor, backgroundColor); } +SumLayout SumLayout::Builder(Layout child0, Layout child1, Layout child2, Layout child3) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(SumLayoutNode)); + SumLayoutNode * node = new (bufferNode) SumLayoutNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, ArrayBuilder(child0, child1, child2, child3).array(), 4); + return static_cast(h); +} + } diff --git a/poincare/src/symbol.cpp b/poincare/src/symbol.cpp index f497b5458..3e28c2ab7 100644 --- a/poincare/src/symbol.cpp +++ b/poincare/src/symbol.cpp @@ -15,6 +15,10 @@ namespace Poincare { constexpr char Symbol::k_ans[]; +SymbolNode::SymbolNode(const char * newName, int length) : SymbolAbstractNode() { + strlcpy(const_cast(name()), newName, length+1); +} + Expression SymbolNode::replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) { return Symbol(this).replaceSymbolWithExpression(symbol, expression); } @@ -77,32 +81,32 @@ bool SymbolNode::isReal(Context & context) const { Layout SymbolNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { if (m_name[0] == Symbol::SpecialSymbols::UnknownX) { assert(m_name[1] == 0); - return CharLayout(Symbol::k_unknownXReadableChar); + return CharLayout::Builder(Symbol::k_unknownXReadableChar); } if (strcmp(m_name, "u(n)") == 0) { return HorizontalLayout::Builder( - CharLayout('u'), + CharLayout::Builder('u'), VerticalOffsetLayout::Builder( - CharLayout('n'), + CharLayout::Builder('n'), VerticalOffsetLayoutNode::Type::Subscript)); } if (strcmp(m_name, "u(n+1)") == 0) { return HorizontalLayout::Builder( - CharLayout('u'), + CharLayout::Builder('u'), VerticalOffsetLayout::Builder( LayoutHelper::String("n+1", 3), VerticalOffsetLayoutNode::Type::Subscript)); } if (strcmp(m_name, "v(n)") == 0) { return HorizontalLayout::Builder( - CharLayout('v'), + CharLayout::Builder('v'), VerticalOffsetLayout::Builder( - CharLayout('n'), + CharLayout::Builder('n'), VerticalOffsetLayoutNode::Type::Subscript)); } if (strcmp(m_name, "v(n+1)") == 0) { return HorizontalLayout::Builder( - CharLayout('v'), + CharLayout::Builder('v'), VerticalOffsetLayout::Builder( LayoutHelper::String("n+1", 3), VerticalOffsetLayoutNode::Type::Subscript)); @@ -135,11 +139,14 @@ Evaluation SymbolNode::templatedApproximate(Context& context, Preferences::Co return e.node()->approximate(T(), context, complexFormat, angleUnit); } -Symbol::Symbol(const char * name, int length) : SymbolAbstract(TreePool::sharedPool()->createTreeNode(SymbolAbstract::AlignedNodeSize(length, sizeof(SymbolNode)))) { - node()->setName(name, length); +Symbol Symbol::Builder(const char * name, int length) { + void * bufferNode = TreePool::sharedPool()->alloc(SymbolAbstract::AlignedNodeSize(length, sizeof(SymbolNode))); + SymbolNode * node = new (bufferNode) SymbolNode(name, length); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); } -Symbol::Symbol(char name) : Symbol(&name, 1) {} +Symbol Symbol::Builder(char name) { return Symbol::Builder(&name, 1); } bool Symbol::isSeriesSymbol(const char * c) { // [NV][1-3] @@ -184,13 +191,13 @@ Expression Symbol::replaceSymbolWithExpression(const SymbolAbstract & symbol, co Expression Symbol::replaceUnknown(const Symbol & symbol) { assert(!symbol.isUninitialized()); assert(symbol.type() == ExpressionNode::Type::Symbol); - return replaceSymbolWithExpression(symbol, Symbol(SpecialSymbols::UnknownX)); + return replaceSymbolWithExpression(symbol, Symbol::Builder(SpecialSymbols::UnknownX)); } int Symbol::getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const { if (strcmp(name(), symbolName) == 0) { - coefficients[0] = Rational(0); - coefficients[1] = Rational(1); + coefficients[0] = Rational::Builder(0); + coefficients[1] = Rational::Builder(1); return 1; } coefficients[0] = clone(); diff --git a/poincare/src/symbol_abstract.cpp b/poincare/src/symbol_abstract.cpp index 188a1cd05..3ea31e3ab 100644 --- a/poincare/src/symbol_abstract.cpp +++ b/poincare/src/symbol_abstract.cpp @@ -8,26 +8,10 @@ namespace Poincare { -void SymbolAbstractNode::setName(const char * newName, int length) { - strlcpy(const_cast(name()), newName, length+1); -} - size_t SymbolAbstractNode::size() const { return SymbolAbstract::AlignedNodeSize(strlen(name()), nodeSize()); } -void SymbolAbstractNode::initToMatchSize(size_t goalSize) { - assert(goalSize != nodeSize()); - assert(goalSize > nodeSize()); - size_t nameSize = goalSize - nodeSize(); - char * modifiableName = const_cast(name()); - for (size_t i = 0; i < nameSize - 1; i++) { - modifiableName[i] = 'a'; - } - modifiableName[nameSize-1] = 0; - assert(size() == goalSize); -} - ExpressionNode::Sign SymbolAbstractNode::sign(Context * context) const { SymbolAbstract s(this); Expression e = SymbolAbstract::Expand(s, *context, false); @@ -74,7 +58,7 @@ Expression SymbolAbstract::Expand(const SymbolAbstract & symbol, Context & conte * symbols are defined circularly. */ e = Expression::ExpressionWithoutSymbols(e, context); if (!e.isUninitialized() && isFunction) { - e = e.replaceSymbolWithExpression(Symbol(Symbol::SpecialSymbols::UnknownX), symbol.childAtIndex(0)); + e = e.replaceSymbolWithExpression(Symbol::Builder(Symbol::SpecialSymbols::UnknownX), symbol.childAtIndex(0)); } return e; } diff --git a/poincare/src/tangent.cpp b/poincare/src/tangent.cpp index 01510753c..cb162eb5a 100644 --- a/poincare/src/tangent.cpp +++ b/poincare/src/tangent.cpp @@ -30,13 +30,20 @@ template Complex TangentNode::computeOnComplex(const std::complex c, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) { std::complex angleInput = Trigonometry::ConvertToRadian(c, angleUnit); std::complex res = std::tan(angleInput); - return Complex(Trigonometry::RoundToMeaningfulDigits(res, angleInput)); + return Complex::Builder(Trigonometry::RoundToMeaningfulDigits(res, angleInput)); } Expression TangentNode::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ReductionTarget target) { return Tangent(this).shallowReduce(context, complexFormat, angleUnit, target); } +Tangent Tangent::Builder(Expression child) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(TangentNode)); + TangentNode * node = new (bufferNode) TangentNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &child, 1); + return static_cast(h); +} + Expression Tangent::shallowReduce(Context & context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ExpressionNode::ReductionTarget target) { { Expression e = Expression::defaultShallowReduce(); diff --git a/poincare/src/tree_handle.cpp b/poincare/src/tree_handle.cpp index 51cd46dc0..7493b56b4 100644 --- a/poincare/src/tree_handle.cpp +++ b/poincare/src/tree_handle.cpp @@ -185,6 +185,32 @@ TreeHandle::TreeHandle(const TreeNode * node) : TreeHandle() { } } +TreeHandle TreeHandle::BuildWithBasicChildren(TreeNode * node, TreeHandle * children, int numberOfChildren) { + assert(node != nullptr); + TreePool * pool = TreePool::sharedPool(); + int expectedNumberOfChildren = node->numberOfChildren(); + /* Ensure the pool is syntaxically correct by creating ghost children for + * nodes that have a fixed, non-zero number of children. */ + for (int i = 0; i < expectedNumberOfChildren; i++) { + GhostNode * ghost = new (pool->alloc(sizeof(GhostNode))) GhostNode(); + ghost->rename(pool->generateIdentifier(), false); + ghost->retain(); + pool->move(node->next(), ghost, 0); + } + node->rename(pool->generateIdentifier(), false); + TreeHandle h = TreeHandle(node); + /* Add or replace ghost children by the children given as arguments if + * possible. */ + for (int i = 0; i < numberOfChildren; i++) { + if (i < expectedNumberOfChildren) { + h.replaceChildAtIndexInPlace(i, children[i]); + } else { + h.addChildAtIndexInPlace(children[i], i, i); + } + } + return h; +} + void TreeHandle::setIdentifierAndRetain(int newId) { m_identifier = newId; if (!isUninitialized()) { diff --git a/poincare/src/tree_pool.cpp b/poincare/src/tree_pool.cpp index 56f928125..9769f299a 100644 --- a/poincare/src/tree_pool.cpp +++ b/poincare/src/tree_pool.cpp @@ -20,19 +20,6 @@ void TreePool::freeIdentifier(int identifier) { } } -template -T * TreePool::createTreeNode(size_t size) { - T * node = new(alloc(size)) T(); - if (size != sizeof(T)) { - /* If the node does not have a standard size, it should init itself so that - * T::size gives the right result, otherwise TreeNode::next() does not work - * and addGhostChildrenAndRename might not work. */ - node->initToMatchSize(size); - } - addGhostChildrenAndRename(node); - return node; -} - void TreePool::move(TreeNode * destination, TreeNode * source, int realNumberOfSourceChildren) { size_t moveSize = source->deepSize(realNumberOfSourceChildren); moveNodes(destination, source, moveSize); @@ -152,17 +139,6 @@ void TreePool::dealloc(TreeNode * node, size_t size) { updateNodeForIdentifierFromNode(node); } -void TreePool::addGhostChildrenAndRename(TreeNode * node) { - /* Ensure the pool is syntaxically correct by creating ghost children for - * nodes that have a fixed, non-zero number of children. */ - for (int i = 0; i < node->numberOfChildren(); i++) { - TreeNode * ghost = createTreeNode(); - ghost->retain(); - move(node->next(), ghost, 0); - } - node->rename(generateIdentifier(), false); -} - void TreePool::discardTreeNode(TreeNode * node) { int nodeIdentifier = node->identifier(); size_t size = node->size(); @@ -202,107 +178,4 @@ void TreePool::freePoolFromNode(TreeNode * firstNodeToDiscard) { m_cursor = reinterpret_cast(firstNodeToDiscard); } -template HorizontalLayoutNode * Poincare::TreePool::createTreeNode(size_t size); -template EmptyLayoutNode * Poincare::TreePool::createTreeNode(size_t size); -template CharLayoutNode * Poincare::TreePool::createTreeNode(size_t size); -template VerticalOffsetLayoutNode * Poincare::TreePool::createTreeNode(size_t size); -template NthRootLayoutNode * Poincare::TreePool::createTreeNode(size_t size); -template FractionLayoutNode * Poincare::TreePool::createTreeNode(size_t size); -template LeftParenthesisLayoutNode * Poincare::TreePool::createTreeNode(size_t size); -template RightParenthesisLayoutNode * Poincare::TreePool::createTreeNode(size_t size); -template AbsoluteValueNode * Poincare::TreePool::createTreeNode(size_t size); -template AdditionNode * Poincare::TreePool::createTreeNode(size_t size); -template ArcCosineNode * Poincare::TreePool::createTreeNode(size_t size); -template ArcSineNode * Poincare::TreePool::createTreeNode(size_t size); -template ArcTangentNode * Poincare::TreePool::createTreeNode(size_t size); -template UndefinedNode * Poincare::TreePool::createTreeNode(size_t size); -template UnrealNode * Poincare::TreePool::createTreeNode(size_t size); -template BinomialCoefficientNode * Poincare::TreePool::createTreeNode(size_t size); -template CeilingNode * Poincare::TreePool::createTreeNode(size_t size); -template OppositeNode * Poincare::TreePool::createTreeNode(size_t size); -template PowerNode * Poincare::TreePool::createTreeNode(size_t size); -template ComplexArgumentNode * Poincare::TreePool::createTreeNode(size_t size); -template ComplexCartesianNode * Poincare::TreePool::createTreeNode(size_t size); -template ConfidenceIntervalNode * Poincare::TreePool::createTreeNode(size_t size); -template ConjugateNode * Poincare::TreePool::createTreeNode(size_t size); -template ConstantNode * Poincare::TreePool::createTreeNode(size_t size); -template CosineNode * Poincare::TreePool::createTreeNode(size_t size); -template DecimalNode * Poincare::TreePool::createTreeNode(size_t size); -template DerivativeNode * Poincare::TreePool::createTreeNode(size_t size); -template DeterminantNode * Poincare::TreePool::createTreeNode(size_t size); -template DivisionNode * Poincare::TreePool::createTreeNode(size_t size); -template DivisionQuotientNode * Poincare::TreePool::createTreeNode(size_t size); -template DivisionRemainderNode * Poincare::TreePool::createTreeNode(size_t size); -template EmptyExpressionNode * Poincare::TreePool::createTreeNode(size_t size); -template FunctionNode * Poincare::TreePool::createTreeNode(size_t size); -template HyperbolicArcCosineNode * Poincare::TreePool::createTreeNode(size_t size); -template HyperbolicArcSineNode * Poincare::TreePool::createTreeNode(size_t size); -template HyperbolicArcTangentNode * Poincare::TreePool::createTreeNode(size_t size); -template HyperbolicCosineNode * Poincare::TreePool::createTreeNode(size_t size); -template SimplePredictionIntervalNode * Poincare::TreePool::createTreeNode(size_t size); -template HyperbolicSineNode * Poincare::TreePool::createTreeNode(size_t size); -template HyperbolicTangentNode * Poincare::TreePool::createTreeNode(size_t size); -template LogarithmNode<2> * Poincare::TreePool::createTreeNode >(size_t size); -template SymbolNode * Poincare::TreePool::createTreeNode(size_t size); -template LogarithmNode<1> * Poincare::TreePool::createTreeNode >(size_t size); -template ParenthesisNode * Poincare::TreePool::createTreeNode(size_t size); -template StoreNode * Poincare::TreePool::createTreeNode(size_t size); -template EqualNode * Poincare::TreePool::createTreeNode(size_t size); -template FactorNode * Poincare::TreePool::createTreeNode(size_t size); -template FactorialNode * Poincare::TreePool::createTreeNode(size_t size); -template FloorNode * Poincare::TreePool::createTreeNode(size_t size); -template FracPartNode * Poincare::TreePool::createTreeNode(size_t size); -template MatrixNode * Poincare::TreePool::createTreeNode(size_t size); -template FloatNode * Poincare::TreePool::createTreeNode >(size_t size); -template GreatCommonDivisorNode * Poincare::TreePool::createTreeNode(size_t size); -template ImaginaryPartNode * Poincare::TreePool::createTreeNode(size_t size); -template IntegerNode * Poincare::TreePool::createTreeNode(size_t size); -template IntegralNode * Poincare::TreePool::createTreeNode(size_t size); -template LeastCommonMultipleNode * Poincare::TreePool::createTreeNode(size_t size); -template MatrixDimensionNode * Poincare::TreePool::createTreeNode(size_t size); -template MatrixInverseNode * Poincare::TreePool::createTreeNode(size_t size); -template MatrixTraceNode * Poincare::TreePool::createTreeNode(size_t size); -template MatrixTransposeNode * Poincare::TreePool::createTreeNode(size_t size); -template MultiplicationNode * Poincare::TreePool::createTreeNode(size_t size); -template NaperianLogarithmNode * Poincare::TreePool::createTreeNode(size_t size); -template NthRootNode * Poincare::TreePool::createTreeNode(size_t size); -template InfinityNode * Poincare::TreePool::createTreeNode(size_t size); -template PermuteCoefficientNode * Poincare::TreePool::createTreeNode(size_t size); -template PredictionIntervalNode * Poincare::TreePool::createTreeNode(size_t size); -template ProductNode * Poincare::TreePool::createTreeNode(size_t size); -template RandintNode * Poincare::TreePool::createTreeNode(size_t size); -template RandomNode * Poincare::TreePool::createTreeNode(size_t size); -template RationalNode * Poincare::TreePool::createTreeNode(size_t size); -template RealPartNode * Poincare::TreePool::createTreeNode(size_t size); -template RoundNode * Poincare::TreePool::createTreeNode(size_t size); -template SignFunctionNode * Poincare::TreePool::createTreeNode(size_t size); -template SineNode * Poincare::TreePool::createTreeNode(size_t size); -template SquareRootNode * Poincare::TreePool::createTreeNode(size_t size); -template SubtractionNode * Poincare::TreePool::createTreeNode(size_t size); -template SumNode * Poincare::TreePool::createTreeNode(size_t size); -template TangentNode * Poincare::TreePool::createTreeNode(size_t size); -template GhostNode * Poincare::TreePool::createTreeNode(size_t size); - -template MatrixLayoutNode* TreePool::createTreeNode(size_t size); -template AbsoluteValueLayoutNode* TreePool::createTreeNode(size_t size); -template ComplexNode* TreePool::createTreeNode >(size_t size); -template ComplexNode* TreePool::createTreeNode >(size_t size); -template MatrixComplexNode* TreePool::createTreeNode >(size_t size); -template MatrixComplexNode* TreePool::createTreeNode >(size_t size); -template BinomialCoefficientLayoutNode* TreePool::createTreeNode(size_t size); -template CeilingLayoutNode* TreePool::createTreeNode(size_t size); -template CondensedSumLayoutNode* TreePool::createTreeNode(size_t size); -template ConjugateLayoutNode* TreePool::createTreeNode(size_t size); -template FloorLayoutNode* TreePool::createTreeNode(size_t size); -template IntegralLayoutNode* TreePool::createTreeNode(size_t size); -template ProductLayoutNode* TreePool::createTreeNode(size_t size); -template SumLayoutNode* TreePool::createTreeNode(size_t size); -template FloatNode* TreePool::createTreeNode >(size_t size); - -template LeftSquareBracketLayoutNode* TreePool::createTreeNode(size_t size); -template RightSquareBracketLayoutNode* TreePool::createTreeNode(size_t size); - -template BlobNode* TreePool::createTreeNode(size_t size); -template PairNode* TreePool::createTreeNode(size_t size); - } diff --git a/poincare/src/trigonometry.cpp b/poincare/src/trigonometry.cpp index 1daeec03f..71e174ca0 100644 --- a/poincare/src/trigonometry.cpp +++ b/poincare/src/trigonometry.cpp @@ -36,7 +36,7 @@ float Trigonometry::characteristicXRange(const Expression & e, Context & context assert(d == 1); /* To compute a, the slope of the expression child(0), we compute the * derivative of child(0) for any x value. */ - Poincare::Derivative derivative = Poincare::Derivative::Builder(e.childAtIndex(0).clone(), Symbol(x, 1), Float(1.0f)); + Poincare::Derivative derivative = Poincare::Derivative::Builder(e.childAtIndex(0).clone(), Symbol::Builder(x, 1), Float::Builder(1.0f)); float a = derivative.node()->approximate(float(), context, Preferences::ComplexFormat::Real, angleUnit).toScalar(); float pi = angleUnit == Preferences::AngleUnit::Radian ? M_PI : 180.0f; return 2.0f*pi/std::fabs(a); @@ -107,13 +107,13 @@ Expression Trigonometry::shallowReduceDirectFunction(Expression & e, Context& co Expression sqrt = Power::Builder( Addition::Builder( - Rational(1), + Rational::Builder(1), Multiplication::Builder( - Rational(-1), - Power::Builder(e.childAtIndex(0).childAtIndex(0), Rational(2)) + Rational::Builder(-1), + Power::Builder(e.childAtIndex(0).childAtIndex(0), Rational::Builder(2)) ) ), - Rational(1,2) + Rational::Builder(1,2) ); // reduce x^2 sqrt.childAtIndex(0).childAtIndex(1).childAtIndex(1).shallowReduce(context, complexFormat, angleUnit, target); @@ -136,12 +136,12 @@ Expression Trigonometry::shallowReduceDirectFunction(Expression & e, Context& co Expression res = Power::Builder( Addition::Builder( - Rational(1), + Rational::Builder(1), Power::Builder( e.type() == ExpressionNode::Type::Cosine ? x : x.clone(), - Rational(2)) + Rational::Builder(2)) ), - Rational(-1,2) + Rational::Builder(-1,2) ); // reduce x^2 @@ -167,7 +167,7 @@ Expression Trigonometry::shallowReduceDirectFunction(Expression & e, Context& co return e.shallowReduce(context, complexFormat, angleUnit, target); } else { // sin(-a) = -sin(a) or tan(-a) = -tan(a) - Multiplication m = Multiplication::Builder(Rational(-1)); + Multiplication m = Multiplication::Builder(Rational::Builder(-1)); e.replaceWithInPlace(m); m.addChildAtIndexInPlace(e, 1, 1); e.shallowReduce(context, complexFormat, angleUnit, target); @@ -220,7 +220,7 @@ Expression Trigonometry::shallowReduceDirectFunction(Expression & e, Context& co } // Step 4.5. Build the new result. Integer rDenominator = r.integerDenominator(); - Expression newR = Rational(div.remainder, rDenominator); + Expression newR = Rational::Builder(div.remainder, rDenominator); Expression rationalParent = angleUnit == Preferences::AngleUnit::Radian ? e.childAtIndex(0) : e; rationalParent.replaceChildAtIndexInPlace(0, newR); newR.shallowReduce(context, complexFormat, angleUnit, target); @@ -233,7 +233,7 @@ Expression Trigonometry::shallowReduceDirectFunction(Expression & e, Context& co unaryCoefficient *= -1; } Expression simplifiedCosine = e.shallowReduce(context, complexFormat, angleUnit, target); // recursive - Multiplication m = Multiplication::Builder(Rational(unaryCoefficient)); + Multiplication m = Multiplication::Builder(Rational::Builder(unaryCoefficient)); simplifiedCosine.replaceWithInPlace(m); m.addChildAtIndexInPlace(simplifiedCosine, 1, 1); return m.shallowReduce(context, complexFormat, angleUnit, target); @@ -278,12 +278,12 @@ Expression Trigonometry::shallowReduceInverseFunction(Expression & e, Context& c * reduced to undef) */ if (target == ExpressionNode::ReductionTarget::User || x.isNumber()) { Expression sign = SignFunction::Builder(x.clone()); - Multiplication m0 = Multiplication::Builder(Rational(1,2), sign, Constant(Ion::Charset::SmallPi)); + Multiplication m0 = Multiplication::Builder(Rational::Builder(1,2), sign, Constant::Builder(Ion::Charset::SmallPi)); sign.shallowReduce(context, complexFormat, angleUnit, target); e.replaceChildAtIndexInPlace(0, x); Addition a = Addition::Builder(m0); e.replaceWithInPlace(a); - Multiplication m1 = Multiplication::Builder(Rational(-1), e); + Multiplication m1 = Multiplication::Builder(Rational::Builder(-1), e); e.shallowReduce(context, complexFormat, angleUnit, target); a.addChildAtIndexInPlace(m1, 1, 1); return a.shallowReduce(context, complexFormat, angleUnit, target); @@ -314,7 +314,7 @@ Expression Trigonometry::shallowReduceInverseFunction(Expression & e, Context& c // The argument was made positive // acos(-x) = pi-acos(x) if (e.type() == ExpressionNode::Type::ArcCosine) { - Expression pi = angleUnit == Preferences::AngleUnit::Radian ? static_cast(Constant(Ion::Charset::SmallPi)) : static_cast(Rational(180)); + Expression pi = angleUnit == Preferences::AngleUnit::Radian ? static_cast(Constant::Builder(Ion::Charset::SmallPi)) : static_cast(Rational::Builder(180)); Subtraction s = Subtraction::Builder(); e.replaceWithInPlace(s); s.replaceChildAtIndexInPlace(0, pi); @@ -323,7 +323,7 @@ Expression Trigonometry::shallowReduceInverseFunction(Expression & e, Context& c return s.shallowReduce(context, complexFormat, angleUnit, target); } else { // asin(-x) = -asin(x) or atan(-x) = -atan(x) - Multiplication m = Multiplication::Builder(Rational(-1)); + Multiplication m = Multiplication::Builder(Rational::Builder(-1)); e.replaceWithInPlace(m); m.addChildAtIndexInPlace(e, 1, 1); e.shallowReduce(context, complexFormat, angleUnit, target); diff --git a/poincare/src/undefined.cpp b/poincare/src/undefined.cpp index 7031aec61..0615d830e 100644 --- a/poincare/src/undefined.cpp +++ b/poincare/src/undefined.cpp @@ -34,6 +34,13 @@ template Evaluation UndefinedNode::templatedApproximate() const { return Complex::Undefined(); } +Undefined Undefined::Builder() { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(UndefinedNode)); + UndefinedNode * node = new (bufferNode) UndefinedNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); +} + template Evaluation UndefinedNode::templatedApproximate() const; template Evaluation UndefinedNode::templatedApproximate() const; } diff --git a/poincare/src/unreal.cpp b/poincare/src/unreal.cpp index 6180455ac..d8d45a25e 100644 --- a/poincare/src/unreal.cpp +++ b/poincare/src/unreal.cpp @@ -20,5 +20,11 @@ int UnrealNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloat return min(Unreal::NameSize(), bufferSize) - 1; } +Unreal Unreal::Builder() { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(UnrealNode)); + UnrealNode * node = new (bufferNode) UnrealNode(); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); } +} diff --git a/poincare/src/variable_context.cpp b/poincare/src/variable_context.cpp index b0ebbbcde..fb36c9fc2 100644 --- a/poincare/src/variable_context.cpp +++ b/poincare/src/variable_context.cpp @@ -15,7 +15,7 @@ VariableContext::VariableContext(const char * name, Context * parentContext) : template void VariableContext::setApproximationForVariable(T value) { - m_value = Float(value); + m_value = Float::Builder(value); } void VariableContext::setExpressionForSymbol(const Expression & expression, const SymbolAbstract & symbol, Context & context) { diff --git a/poincare/src/vertical_offset_layout.cpp b/poincare/src/vertical_offset_layout.cpp index 69feb1557..5686e6f16 100644 --- a/poincare/src/vertical_offset_layout.cpp +++ b/poincare/src/vertical_offset_layout.cpp @@ -266,4 +266,11 @@ LayoutNode * VerticalOffsetLayoutNode::baseLayout() { return parentNode->childAtIndex(idxInParent - 1); } +VerticalOffsetLayout VerticalOffsetLayout::Builder(Layout l, VerticalOffsetLayoutNode::Type type) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(VerticalOffsetLayoutNode)); + VerticalOffsetLayoutNode * node = new (bufferNode) VerticalOffsetLayoutNode(type); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, &l, 1); + return static_cast(h); +} + } diff --git a/poincare/test/addition.cpp b/poincare/test/addition.cpp index 49803abba..f7588f627 100644 --- a/poincare/test/addition.cpp +++ b/poincare/test/addition.cpp @@ -22,8 +22,8 @@ static inline void assert_parsed_expression_is_equal_to(const char * exp, Expres } QUIZ_CASE(poincare_addition_cast_does_not_copy) { - Rational i1(1); - Rational i2(2); + Rational i1 = Rational::Builder(1); + Rational i2 = Rational::Builder(2); Addition j = Addition::Builder(i1, i2); Expression k = j; quiz_assert(k.identifier() == (static_cast(k)).identifier()); @@ -32,15 +32,15 @@ QUIZ_CASE(poincare_addition_cast_does_not_copy) { } QUIZ_CASE(poincare_addition_without_parsing) { - Rational i1(1); - Rational i2(2); + Rational i1 = Rational::Builder(1); + Rational i2 = Rational::Builder(2); Addition j = Addition::Builder(i1, i2); assert_approximation_equals(j, 3.0f); } QUIZ_CASE(poincare_addition_parsing) { - Rational i1(1); - Rational i2(2); + Rational i1 = Rational::Builder(1); + Rational i2 = Rational::Builder(2); Addition j1 = Addition::Builder(i1, i2); assert_parsed_expression_is_equal_to("1+2", j1); } diff --git a/poincare/test/convert_expression_to_text.cpp b/poincare/test/convert_expression_to_text.cpp index 7656bd7b1..85d81c602 100644 --- a/poincare/test/convert_expression_to_text.cpp +++ b/poincare/test/convert_expression_to_text.cpp @@ -189,100 +189,100 @@ QUIZ_CASE(assert_float_prints_to) { } QUIZ_CASE(poincare_rational_to_text) { - assert_expression_prints_to(Rational(2,3), "2/3"); - assert_expression_prints_to(Rational("12345678910111213","123456789101112131"), "12345678910111213/123456789101112131"); - assert_expression_prints_to(Rational("123456789112345678921234567893123456789412345678951234567896123456789612345678971234567898123456789912345678901234567891123456789212345678931234567894123456789512345678961234567896123456789712345678981234567899123456789","1"), "123456789112345678921234567893123456789412345678951234567896123456789612345678971234567898123456789912345678901234567891123456789212345678931234567894123456789512345678961234567896123456789712345678981234567899123456789"); + assert_expression_prints_to(Rational::Builder(2,3), "2/3"); + assert_expression_prints_to(Rational::Builder("12345678910111213","123456789101112131"), "12345678910111213/123456789101112131"); + assert_expression_prints_to(Rational::Builder("123456789112345678921234567893123456789412345678951234567896123456789612345678971234567898123456789912345678901234567891123456789212345678931234567894123456789512345678961234567896123456789712345678981234567899123456789","1"), "123456789112345678921234567893123456789412345678951234567896123456789612345678971234567898123456789912345678901234567891123456789212345678931234567894123456789512345678961234567896123456789712345678981234567899123456789"); } QUIZ_CASE(poincare_decimal_to_text) { - Decimal d0(Integer("-123456789"),30); + Decimal d0 = Decimal::Builder(Integer("-123456789"),30); assert_expression_prints_to(d0, "-1.23456789E30", ScientificMode, 14); assert_expression_prints_to(d0, "-1.234568E30", DecimalMode, 7); - Decimal d1(Integer("123456789"),30); + Decimal d1 = Decimal::Builder(Integer("123456789"),30); assert_expression_prints_to(d1, "1.23456789E30", ScientificMode, 14); assert_expression_prints_to(d1, "1.235E30", DecimalMode, 4); - Decimal d2(Integer("-123456789"),-30); + Decimal d2 = Decimal::Builder(Integer("-123456789"),-30); assert_expression_prints_to(d2, "-1.23456789E-30", DecimalMode, 14); assert_expression_prints_to(d2, "-1.235E-30", ScientificMode, 4); - Decimal d3(Integer("-12345"),-3); + Decimal d3 = Decimal::Builder(Integer("-12345"),-3); assert_expression_prints_to(d3, "-0.0012345", DecimalMode, 7); assert_expression_prints_to(d3, "-0.00123", DecimalMode, 3); assert_expression_prints_to(d3, "-0.001235", DecimalMode, 4); assert_expression_prints_to(d3, "-1.23E-3", ScientificMode, 3); - Decimal d4(Integer("12345"),-3); + Decimal d4 = Decimal::Builder(Integer("12345"),-3); assert_expression_prints_to(d4, "0.0012345", DecimalMode, 7); assert_expression_prints_to(d4, "1.2E-3", ScientificMode, 2); - Decimal d5(Integer("12345"),3); + Decimal d5 = Decimal::Builder(Integer("12345"),3); assert_expression_prints_to(d5, "1234.5", DecimalMode, 7); assert_expression_prints_to(d5, "1.23E3", DecimalMode, 3); assert_expression_prints_to(d5, "1235", DecimalMode, 4); assert_expression_prints_to(d5, "1.235E3", ScientificMode, 4); - Decimal d6(Integer("-12345"),3); + Decimal d6 = Decimal::Builder(Integer("-12345"),3); assert_expression_prints_to(d6, "-1234.5", DecimalMode, 7); assert_expression_prints_to(d6, "-1.2345E3", ScientificMode, 10); - Decimal d7(Integer("12345"),6); + Decimal d7 = Decimal::Builder(Integer("12345"),6); assert_expression_prints_to(d7, "1234500", DecimalMode, 7); assert_expression_prints_to(d7, "1.2345E6", DecimalMode, 6); assert_expression_prints_to(d7, "1.2345E6", ScientificMode); - Decimal d8(Integer("-12345"),6); + Decimal d8 = Decimal::Builder(Integer("-12345"),6); assert_expression_prints_to(d8, "-1234500", DecimalMode, 7); assert_expression_prints_to(d8, "-1.2345E6", DecimalMode, 5); assert_expression_prints_to(d7, "1.235E6", ScientificMode, 4); - Decimal d9(Integer("-12345"),-1); + Decimal d9 = Decimal::Builder(Integer("-12345"),-1); assert_expression_prints_to(d9, "-0.12345", DecimalMode, 7); assert_expression_prints_to(d9, "-0.1235", DecimalMode, 4); assert_expression_prints_to(d9, "-1.235E-1", ScientificMode, 4); - Decimal d10(Integer("12345"),-1); + Decimal d10 = Decimal::Builder(Integer("12345"),-1); assert_expression_prints_to(d10, "1.2345E-1"); assert_expression_prints_to(d10, "0.12345", DecimalMode, 7); assert_expression_prints_to(d10, "0.1235", DecimalMode, 4); assert_expression_prints_to(d10, "1.235E-1", ScientificMode, 4); - assert_expression_prints_to(Decimal(-1.23456789E30), "-1.23456789E30", ScientificMode, 14); - assert_expression_prints_to(Decimal(1.23456789E30), "1.23456789E30", ScientificMode, 14); - assert_expression_prints_to(Decimal(-1.23456789E-30), "-1.23456789E-30", ScientificMode, 14); - assert_expression_prints_to(Decimal(-1.2345E-3), "-0.0012345", DecimalMode); - assert_expression_prints_to(Decimal(1.2345E-3), "0.0012345", DecimalMode); - assert_expression_prints_to(Decimal(1.2345E3), "1234.5", DecimalMode); - assert_expression_prints_to(Decimal(-1.2345E3), "-1234.5", DecimalMode); - assert_expression_prints_to(Decimal(1.2345E6), "1234500", DecimalMode); - assert_expression_prints_to(Decimal(-1.2345E6), "-1234500", DecimalMode); - assert_expression_prints_to(Decimal(-1.2345E-1), "-0.12345", DecimalMode); - assert_expression_prints_to(Decimal(1.2345E-1), "0.12345", DecimalMode); - assert_expression_prints_to(Decimal(1.0), "1"); - assert_expression_prints_to(Decimal(0.9999999999999996), "1"); - assert_expression_prints_to(Decimal(0.99999999999995), "9.9999999999995E-1", ScientificMode, 14); - assert_expression_prints_to(Decimal(0.00000099999999999995), "9.9999999999995E-7", ScientificMode, 14); - assert_expression_prints_to(Decimal(0.000000999999999999995), "0.000001", DecimalMode); - assert_expression_prints_to(Decimal(0.000000999999999901200121020102010201201201021099995), "9.999999999012E-7", DecimalMode, 14); - assert_expression_prints_to(Decimal(9999999999999.54), "9999999999999.5", DecimalMode, 14); - assert_expression_prints_to(Decimal(99999999999999.54), "1E14", DecimalMode, 14); - assert_expression_prints_to(Decimal(999999999999999.54), "1E15", DecimalMode, 14); - assert_expression_prints_to(Decimal(9999999999999999.54), "1E16", DecimalMode, 14); - assert_expression_prints_to(Decimal(-9.702365051313E-297), "-9.702365051313E-297", DecimalMode, 14); + assert_expression_prints_to(Decimal::Builder(-1.23456789E30), "-1.23456789E30", ScientificMode, 14); + assert_expression_prints_to(Decimal::Builder(1.23456789E30), "1.23456789E30", ScientificMode, 14); + assert_expression_prints_to(Decimal::Builder(-1.23456789E-30), "-1.23456789E-30", ScientificMode, 14); + assert_expression_prints_to(Decimal::Builder(-1.2345E-3), "-0.0012345", DecimalMode); + assert_expression_prints_to(Decimal::Builder(1.2345E-3), "0.0012345", DecimalMode); + assert_expression_prints_to(Decimal::Builder(1.2345E3), "1234.5", DecimalMode); + assert_expression_prints_to(Decimal::Builder(-1.2345E3), "-1234.5", DecimalMode); + assert_expression_prints_to(Decimal::Builder(1.2345E6), "1234500", DecimalMode); + assert_expression_prints_to(Decimal::Builder(-1.2345E6), "-1234500", DecimalMode); + assert_expression_prints_to(Decimal::Builder(-1.2345E-1), "-0.12345", DecimalMode); + assert_expression_prints_to(Decimal::Builder(1.2345E-1), "0.12345", DecimalMode); + assert_expression_prints_to(Decimal::Builder(1.0), "1"); + assert_expression_prints_to(Decimal::Builder(0.9999999999999996), "1"); + assert_expression_prints_to(Decimal::Builder(0.99999999999995), "9.9999999999995E-1", ScientificMode, 14); + assert_expression_prints_to(Decimal::Builder(0.00000099999999999995), "9.9999999999995E-7", ScientificMode, 14); + assert_expression_prints_to(Decimal::Builder(0.000000999999999999995), "0.000001", DecimalMode); + assert_expression_prints_to(Decimal::Builder(0.000000999999999901200121020102010201201201021099995), "9.999999999012E-7", DecimalMode, 14); + assert_expression_prints_to(Decimal::Builder(9999999999999.54), "9999999999999.5", DecimalMode, 14); + assert_expression_prints_to(Decimal::Builder(99999999999999.54), "1E14", DecimalMode, 14); + assert_expression_prints_to(Decimal::Builder(999999999999999.54), "1E15", DecimalMode, 14); + assert_expression_prints_to(Decimal::Builder(9999999999999999.54), "1E16", DecimalMode, 14); + assert_expression_prints_to(Decimal::Builder(-9.702365051313E-297), "-9.702365051313E-297", DecimalMode, 14); } QUIZ_CASE(poincare_approximation_to_text) { - assert_expression_prints_to(Float(-1.23456789E30), "-1.23456789E30", DecimalMode, 14); - assert_expression_prints_to(Float(1.23456789E30), "1.23456789E30", DecimalMode, 14); - assert_expression_prints_to(Float(-1.23456789E-30), "-1.23456789E-30", DecimalMode, 14); - assert_expression_prints_to(Float(-1.2345E-3), "-0.0012345", DecimalMode); - assert_expression_prints_to(Float(1.2345E-3), "0.0012345", DecimalMode); - assert_expression_prints_to(Float(1.2345E3), "1234.5", DecimalMode); - assert_expression_prints_to(Float(-1.2345E3), "-1234.5", DecimalMode); - assert_expression_prints_to(Float(0.99999999999995), "9.9999999999995E-1", ScientificMode, 14); - assert_expression_prints_to(Float(0.00000099999999999995), "9.9999999999995E-7", DecimalMode, 14); - assert_expression_prints_to(Float(0.0000009999999999901200121020102010201201201021099995), "9.9999999999012E-7", DecimalMode, 14); - assert_expression_prints_to(Float(1.2345E-1), "0.12345", DecimalMode); - assert_expression_prints_to(Float(1), "1", DecimalMode); - assert_expression_prints_to(Float(0.9999999999999995), "1", DecimalMode); - assert_expression_prints_to(Float(1.2345E6), "1234500", DecimalMode); - assert_expression_prints_to(Float(-1.2345E6), "-1234500", DecimalMode); - assert_expression_prints_to(Float(0.0000009999999999999995), "0.000001", DecimalMode); - assert_expression_prints_to(Float(-1.2345E-1), "-0.12345", DecimalMode); + assert_expression_prints_to(Float::Builder(-1.23456789E30), "-1.23456789E30", DecimalMode, 14); + assert_expression_prints_to(Float::Builder(1.23456789E30), "1.23456789E30", DecimalMode, 14); + assert_expression_prints_to(Float::Builder(-1.23456789E-30), "-1.23456789E-30", DecimalMode, 14); + assert_expression_prints_to(Float::Builder(-1.2345E-3), "-0.0012345", DecimalMode); + assert_expression_prints_to(Float::Builder(1.2345E-3), "0.0012345", DecimalMode); + assert_expression_prints_to(Float::Builder(1.2345E3), "1234.5", DecimalMode); + assert_expression_prints_to(Float::Builder(-1.2345E3), "-1234.5", DecimalMode); + assert_expression_prints_to(Float::Builder(0.99999999999995), "9.9999999999995E-1", ScientificMode, 14); + assert_expression_prints_to(Float::Builder(0.00000099999999999995), "9.9999999999995E-7", DecimalMode, 14); + assert_expression_prints_to(Float::Builder(0.0000009999999999901200121020102010201201201021099995), "9.9999999999012E-7", DecimalMode, 14); + assert_expression_prints_to(Float::Builder(1.2345E-1), "0.12345", DecimalMode); + assert_expression_prints_to(Float::Builder(1), "1", DecimalMode); + assert_expression_prints_to(Float::Builder(0.9999999999999995), "1", DecimalMode); + assert_expression_prints_to(Float::Builder(1.2345E6), "1234500", DecimalMode); + assert_expression_prints_to(Float::Builder(-1.2345E6), "-1234500", DecimalMode); + assert_expression_prints_to(Float::Builder(0.0000009999999999999995), "0.000001", DecimalMode); + assert_expression_prints_to(Float::Builder(-1.2345E-1), "-0.12345", DecimalMode); - assert_expression_prints_to(Float(INFINITY), Infinity::Name(), DecimalMode); - assert_expression_prints_to(Float(0.0f), "0", DecimalMode); - assert_expression_prints_to(Float(NAN), Undefined::Name(), DecimalMode); + assert_expression_prints_to(Float::Builder(INFINITY), Infinity::Name(), DecimalMode); + assert_expression_prints_to(Float::Builder(0.0f), "0", DecimalMode); + assert_expression_prints_to(Float::Builder(NAN), Undefined::Name(), DecimalMode); } diff --git a/poincare/test/decimal.cpp b/poincare/test/decimal.cpp index 50a4c1e48..bb91c0114 100644 --- a/poincare/test/decimal.cpp +++ b/poincare/test/decimal.cpp @@ -8,10 +8,10 @@ using namespace Poincare; QUIZ_CASE(poincare_decimal_constructor) { int initialPoolSize = pool_size(); - Decimal a("123",2); - Decimal b("3456", -4); - Decimal c(2.34f); - Decimal d(2322.34); + Decimal a = Decimal::Builder("123",2); + Decimal b = Decimal::Builder("3456", -4); + Decimal c = Decimal::Builder(2.34f); + Decimal d = Decimal::Builder(2322.34); assert_pool_size(initialPoolSize+4); } @@ -24,23 +24,23 @@ static inline void assert_not_equal(const Decimal i, const Decimal j) { } QUIZ_CASE(poincare_decimal_compare) { - assert_equal(Decimal("25", 3), Decimal("25", 3)); - assert_equal(Decimal("1000", -3), Decimal("1", -3)); - assert_equal(Decimal("1000", 3), Decimal("1", 3)); - assert_not_equal(Decimal(123,234), Decimal(42, 108)); - assert_not_equal(Decimal(12,2), Decimal(123, 2)); - assert_not_equal(Decimal(1234,2), Decimal(1234,3)); - assert_not_equal(Decimal(12345,2), Decimal(1235,2)); - assert_not_equal(Decimal(123456, -2),Decimal(1234567, -3)); - assert_not_equal(Decimal(12345678, -2),Decimal(1234567, -2)); + assert_equal(Decimal::Builder("25", 3), Decimal::Builder("25", 3)); + assert_equal(Decimal::Builder("1000", -3), Decimal::Builder("1", -3)); + assert_equal(Decimal::Builder("1000", 3), Decimal::Builder("1", 3)); + assert_not_equal(Decimal::Builder(123,234), Decimal::Builder(42, 108)); + assert_not_equal(Decimal::Builder(12,2), Decimal::Builder(123, 2)); + assert_not_equal(Decimal::Builder(1234,2), Decimal::Builder(1234,3)); + assert_not_equal(Decimal::Builder(12345,2), Decimal::Builder(1235,2)); + assert_not_equal(Decimal::Builder(123456, -2),Decimal::Builder(1234567, -3)); + assert_not_equal(Decimal::Builder(12345678, -2),Decimal::Builder(1234567, -2)); } QUIZ_CASE(poincare_decimal_properties) { - quiz_assert(Decimal(-2, 3).sign() == ExpressionNode::Sign::Negative); - quiz_assert(Decimal(-2, -3).sign() == ExpressionNode::Sign::Negative); - quiz_assert(Decimal(2, -3).sign() == ExpressionNode::Sign::Positive); - quiz_assert(Decimal(2, 3).sign() == ExpressionNode::Sign::Positive); - quiz_assert(Decimal(0, 1).sign() == ExpressionNode::Sign::Positive); + quiz_assert(Decimal::Builder(-2, 3).sign() == ExpressionNode::Sign::Negative); + quiz_assert(Decimal::Builder(-2, -3).sign() == ExpressionNode::Sign::Negative); + quiz_assert(Decimal::Builder(2, -3).sign() == ExpressionNode::Sign::Positive); + quiz_assert(Decimal::Builder(2, 3).sign() == ExpressionNode::Sign::Positive); + quiz_assert(Decimal::Builder(0, 1).sign() == ExpressionNode::Sign::Positive); } // Simplify diff --git a/poincare/test/expression.cpp b/poincare/test/expression.cpp index 0f80f49fc..3881823bb 100644 --- a/poincare/test/expression.cpp +++ b/poincare/test/expression.cpp @@ -7,7 +7,7 @@ using namespace Poincare; QUIZ_CASE(expression_can_start_uninitialized) { Expression e; { - Rational i(1); + Rational i = Rational::Builder(1); e = i; } } diff --git a/poincare/test/expression_order.cpp b/poincare/test/expression_order.cpp index 2b2ca3408..3e90aa0c6 100644 --- a/poincare/test/expression_order.cpp +++ b/poincare/test/expression_order.cpp @@ -23,24 +23,24 @@ void assert_multiplication_or_addition_is_ordered_as(Expression e1, Expression e QUIZ_CASE(poincare_expression_order) { { // 2 * 5 - Expression e1 = Multiplication::Builder(Rational(5), Rational(2)); - Expression e2 = Multiplication::Builder(Rational(2), Rational(5)); + Expression e1 = Multiplication::Builder(Rational::Builder(5), Rational::Builder(2)); + Expression e2 = Multiplication::Builder(Rational::Builder(2), Rational::Builder(5)); assert_multiplication_or_addition_is_ordered_as(e1, e2); } { // 2 + 1 + 0 constexpr int numberOfChildren = 3; - Expression children[numberOfChildren] = {Rational(1), Rational(2), Rational(0)}; - Expression childrenSorted[numberOfChildren] = {Rational(2), Rational(1), Rational(0)}; + Expression children[numberOfChildren] = {Rational::Builder(1), Rational::Builder(2), Rational::Builder(0)}; + Expression childrenSorted[numberOfChildren] = {Rational::Builder(2), Rational::Builder(1), Rational::Builder(0)}; Expression e1 = Addition::Builder(children, numberOfChildren); Expression e2 = Addition::Builder(childrenSorted, numberOfChildren); assert_multiplication_or_addition_is_ordered_as(e1, e2); } { // e + pi + i - Expression pi = Constant(Ion::Charset::SmallPi); - Expression i = Constant(Ion::Charset::IComplex); - Expression e = Constant(Ion::Charset::Exponential); + Expression pi = Constant::Builder(Ion::Charset::SmallPi); + Expression i = Constant::Builder(Ion::Charset::IComplex); + Expression e = Constant::Builder(Ion::Charset::Exponential); constexpr int numberOfChildren = 3; Expression children[numberOfChildren] = {pi.clone(), i.clone(), e.clone()}; Expression childrenSorted[numberOfChildren] = {e, pi, i}; @@ -50,23 +50,23 @@ QUIZ_CASE(poincare_expression_order) { } { // 2 * root(3) - Expression e1 = Multiplication::Builder(SquareRoot::Builder(Rational(3)), Rational(2)); - Expression e2 = Multiplication::Builder(Rational(2), SquareRoot::Builder(Rational(3))); + Expression e1 = Multiplication::Builder(SquareRoot::Builder(Rational::Builder(3)), Rational::Builder(2)); + Expression e2 = Multiplication::Builder(Rational::Builder(2), SquareRoot::Builder(Rational::Builder(3))); assert_multiplication_or_addition_is_ordered_as(e1, e2); } { constexpr int numberOfChildren = 4; Expression children[numberOfChildren] = { - Symbol('c'), - Power::Builder(Symbol('b'), Rational(2)), - Power::Builder(Symbol('a'), Rational(2)), - Symbol('a') + Symbol::Builder('c'), + Power::Builder(Symbol::Builder('b'), Rational::Builder(2)), + Power::Builder(Symbol::Builder('a'), Rational::Builder(2)), + Symbol::Builder('a') }; Expression childrenSorted[numberOfChildren] = { - Power::Builder(Symbol('a'), Rational(2)), - Symbol('a'), - Power::Builder(Symbol('b'), Rational(2)), - Symbol('c') + Power::Builder(Symbol::Builder('a'), Rational::Builder(2)), + Symbol::Builder('a'), + Power::Builder(Symbol::Builder('b'), Rational::Builder(2)), + Symbol::Builder('c') }; // a^2 + a + b^2 + c Expression e1 = Addition::Builder(children, numberOfChildren); @@ -75,32 +75,32 @@ QUIZ_CASE(poincare_expression_order) { } { // 2*x^3 + 3*x^2 - Expression child1 = Multiplication::Builder(Rational(2), Power::Builder(Symbol('x'), Rational(3))); - Expression child2 = Multiplication::Builder(Rational(3), Power::Builder(Symbol('x'), Rational(2))); + Expression child1 = Multiplication::Builder(Rational::Builder(2), Power::Builder(Symbol::Builder('x'), Rational::Builder(3))); + Expression child2 = Multiplication::Builder(Rational::Builder(3), Power::Builder(Symbol::Builder('x'), Rational::Builder(2))); Expression e1 = Addition::Builder(child2.clone(), child1.clone()); Expression e2 = Addition::Builder(child1, child2); assert_multiplication_or_addition_is_ordered_as(e1, e2); } { // 3*x + 2*x - Expression child1 = Multiplication::Builder(Rational(3), Symbol('x')); - Expression child2 = Multiplication::Builder(Rational(2), Symbol('x')); + Expression child1 = Multiplication::Builder(Rational::Builder(3), Symbol::Builder('x')); + Expression child2 = Multiplication::Builder(Rational::Builder(2), Symbol::Builder('x')); Expression e1 = Addition::Builder(child2.clone(), child1.clone()); Expression e2 = Addition::Builder(child1, child2); assert_multiplication_or_addition_is_ordered_as(e1, e2); } { // pi^a * pi^b - Expression child1 = Power::Builder(Constant(Ion::Charset::SmallPi), Symbol('a')); - Expression child2 = Power::Builder(Constant(Ion::Charset::SmallPi), Symbol('b')); + Expression child1 = Power::Builder(Constant::Builder(Ion::Charset::SmallPi), Symbol::Builder('a')); + Expression child2 = Power::Builder(Constant::Builder(Ion::Charset::SmallPi), Symbol::Builder('b')); Expression e1 = Multiplication::Builder(child2.clone(), child1.clone()); Expression e2 = Multiplication::Builder(child1, child2); assert_multiplication_or_addition_is_ordered_as(e1, e2); } { // pi^2 * pi^3 - Expression child1 = Power::Builder(Constant(Ion::Charset::SmallPi), Rational(2)); - Expression child2 = Power::Builder(Constant(Ion::Charset::SmallPi), Rational(3)); + Expression child1 = Power::Builder(Constant::Builder(Ion::Charset::SmallPi), Rational::Builder(2)); + Expression child2 = Power::Builder(Constant::Builder(Ion::Charset::SmallPi), Rational::Builder(3)); Expression e1 = Multiplication::Builder(child2.clone(), child1.clone()); Expression e2 = Multiplication::Builder(child1, child2); assert_multiplication_or_addition_is_ordered_as(e1, e2); diff --git a/poincare/test/float.cpp b/poincare/test/float.cpp index d605cf819..1a17527a3 100644 --- a/poincare/test/float.cpp +++ b/poincare/test/float.cpp @@ -22,26 +22,26 @@ void assert_float_evaluates_to(Float f, const char * result) { } QUIZ_CASE(poincare_float_evaluate) { - assert_float_evaluates_to(Float(-1.23456789E30), "-1.23456789E30"); - assert_float_evaluates_to(Float(1.23456789E30), "1.23456789E30"); - assert_float_evaluates_to(Float(-1.23456789E-30), "-1.23456789E-30"); - assert_float_evaluates_to(Float(-1.2345E-3), "-0.0012345"); - assert_float_evaluates_to(Float(1.2345E-3), "0.0012345"); - assert_float_evaluates_to(Float(1.2345E3), "1234.5"); - assert_float_evaluates_to(Float(-1.2345E3), "-1234.5"); - assert_float_evaluates_to(Float(0.99999999999995), "9.9999999999995E-1"); - assert_float_evaluates_to(Float(0.00000099999999999995), "9.9999999999995E-7"); - assert_float_evaluates_to(Float(0.0000009999999999901200121020102010201201201021099995), "9.9999999999012E-7"); - assert_float_evaluates_to(Float(1.2345E-1), "0.12345"); - assert_float_evaluates_to(Float(1), "1"); - assert_float_evaluates_to(Float(0.9999999999999995), "1"); - assert_float_evaluates_to(Float(1.2345E6), "1234500"); - assert_float_evaluates_to(Float(-1.2345E6), "-1234500"); - assert_float_evaluates_to(Float(0.0000009999999999999995), "0.000001"); - assert_float_evaluates_to(Float(-1.2345E-1), "-0.12345"); + assert_float_evaluates_to(Float::Builder(-1.23456789E30), "-1.23456789E30"); + assert_float_evaluates_to(Float::Builder(1.23456789E30), "1.23456789E30"); + assert_float_evaluates_to(Float::Builder(-1.23456789E-30), "-1.23456789E-30"); + assert_float_evaluates_to(Float::Builder(-1.2345E-3), "-0.0012345"); + assert_float_evaluates_to(Float::Builder(1.2345E-3), "0.0012345"); + assert_float_evaluates_to(Float::Builder(1.2345E3), "1234.5"); + assert_float_evaluates_to(Float::Builder(-1.2345E3), "-1234.5"); + assert_float_evaluates_to(Float::Builder(0.99999999999995), "9.9999999999995E-1"); + assert_float_evaluates_to(Float::Builder(0.00000099999999999995), "9.9999999999995E-7"); + assert_float_evaluates_to(Float::Builder(0.0000009999999999901200121020102010201201201021099995), "9.9999999999012E-7"); + assert_float_evaluates_to(Float::Builder(1.2345E-1), "0.12345"); + assert_float_evaluates_to(Float::Builder(1), "1"); + assert_float_evaluates_to(Float::Builder(0.9999999999999995), "1"); + assert_float_evaluates_to(Float::Builder(1.2345E6), "1234500"); + assert_float_evaluates_to(Float::Builder(-1.2345E6), "-1234500"); + assert_float_evaluates_to(Float::Builder(0.0000009999999999999995), "0.000001"); + assert_float_evaluates_to(Float::Builder(-1.2345E-1), "-0.12345"); - assert_float_evaluates_to(Float(INFINITY), Infinity::Name()); - assert_float_evaluates_to(Float(0.0f), "0"); - assert_float_evaluates_to(Float(NAN), Undefined::Name()); + assert_float_evaluates_to(Float::Builder(INFINITY), Infinity::Name()); + assert_float_evaluates_to(Float::Builder(0.0f), "0"); + assert_float_evaluates_to(Float::Builder(NAN), Undefined::Name()); } diff --git a/poincare/test/fraction_layout.cpp b/poincare/test/fraction_layout.cpp index 9d38c8691..51417ed3f 100644 --- a/poincare/test/fraction_layout.cpp +++ b/poincare/test/fraction_layout.cpp @@ -41,11 +41,11 @@ QUIZ_CASE(poincare_fraction_layout_delete) { * |3 * */ HorizontalLayout layout2 = HorizontalLayout::Builder( - CharLayout('1'), - CharLayout('+'), + CharLayout::Builder('1'), + CharLayout::Builder('+'), FractionLayout::Builder( - EmptyLayout(), - CharLayout('3') + EmptyLayout::Builder(), + CharLayout::Builder('3') ) ); LayoutCursor cursor2(layout2.childAtIndex(2).childAtIndex(1), LayoutCursor::Position::Left); @@ -56,7 +56,7 @@ QUIZ_CASE(poincare_fraction_layout_delete) { QUIZ_CASE(poincare_fraction_layout_serialize) { FractionLayout layout = FractionLayout::Builder( - CharLayout('1'), + CharLayout::Builder('1'), LayoutHelper::String("2+3", 3) ); assert_expression_layout_serialize_to(layout, "(1)/(2+3)"); diff --git a/poincare/test/layouts.cpp b/poincare/test/layouts.cpp index a69665b59..c8ee32a97 100644 --- a/poincare/test/layouts.cpp +++ b/poincare/test/layouts.cpp @@ -42,9 +42,9 @@ void assert_parsed_layout_is(Layout l, Poincare::Expression r) { } QUIZ_CASE(poincare_create_all_layouts) { - EmptyLayout e0; + EmptyLayout e0 = EmptyLayout::Builder(); AbsoluteValueLayout e1 = AbsoluteValueLayout::Builder(e0); - CharLayout e2('a'); + CharLayout e2 = CharLayout::Builder('a'); BinomialCoefficientLayout e3 = BinomialCoefficientLayout::Builder(e1, e2); CeilingLayout e4 = CeilingLayout::Builder(e3); RightParenthesisLayout e5 = RightParenthesisLayout::Builder(); @@ -59,13 +59,13 @@ QUIZ_CASE(poincare_create_all_layouts) { IntegralLayout e15 = IntegralLayout::Builder(e11, e12, e13, e14); NthRootLayout e16 = NthRootLayout::Builder(e15); MatrixLayout e17 = MatrixLayout::Builder(); - EmptyLayout e18; - EmptyLayout e19; - EmptyLayout e20; + EmptyLayout e18 = EmptyLayout::Builder(); + EmptyLayout e19 = EmptyLayout::Builder(); + EmptyLayout e20 = EmptyLayout::Builder(); ProductLayout e21 = ProductLayout::Builder(e17, e18, e19, e20); - EmptyLayout e22; - EmptyLayout e23; - EmptyLayout e24; + EmptyLayout e22 = EmptyLayout::Builder(); + EmptyLayout e23 = EmptyLayout::Builder(); + EmptyLayout e24 = EmptyLayout::Builder(); SumLayout e25 = SumLayout::Builder(e21, e22, e23, e24); VerticalOffsetLayout e26 = VerticalOffsetLayout::Builder(e25, VerticalOffsetLayoutNode::Type::Superscript); } @@ -82,194 +82,194 @@ QUIZ_CASE(poincare_parse_layouts) { // 1+2 l = HorizontalLayout::Builder( - CharLayout('1'), - CharLayout('+'), - CharLayout('2')); - e = Addition::Builder(Rational(1), Rational(2)); + CharLayout::Builder('1'), + CharLayout::Builder('+'), + CharLayout::Builder('2')); + e = Addition::Builder(Rational::Builder(1), Rational::Builder(2)); assert_parsed_layout_is(l, e); // |3+3/6| l = AbsoluteValueLayout:: Builder( HorizontalLayout::Builder( - CharLayout('3'), - CharLayout('+'), + CharLayout::Builder('3'), + CharLayout::Builder('+'), FractionLayout::Builder( - CharLayout('3'), - CharLayout('6')))); + CharLayout::Builder('3'), + CharLayout::Builder('6')))); e = AbsoluteValue::Builder( Addition::Builder( - Rational(3), + Rational::Builder(3), Division::Builder( - Rational(3), - Rational(6)))); + Rational::Builder(3), + Rational::Builder(6)))); assert_parsed_layout_is(l, e); // binCoef(4,5) l = BinomialCoefficientLayout::Builder( - CharLayout('4'), - CharLayout('5')); + CharLayout::Builder('4'), + CharLayout::Builder('5')); e = BinomialCoefficient::Builder( - Rational(4), - Rational(5)); + Rational::Builder(4), + Rational::Builder(5)); assert_parsed_layout_is(l, e); // ceil(4.6) l = CeilingLayout::Builder( HorizontalLayout::Builder( - CharLayout('4'), - CharLayout('.'), - CharLayout('6'))); + CharLayout::Builder('4'), + CharLayout::Builder('.'), + CharLayout::Builder('6'))); e = Ceiling::Builder( - Decimal(4.6)); + Decimal::Builder(4.6)); assert_parsed_layout_is(l, e); // floor(7.2) l = FloorLayout::Builder( HorizontalLayout::Builder( - CharLayout('7'), - CharLayout('.'), - CharLayout('2'))); + CharLayout::Builder('7'), + CharLayout::Builder('.'), + CharLayout::Builder('2'))); e = Floor::Builder( - Decimal(7.2)); + Decimal::Builder(7.2)); assert_parsed_layout_is(l, e); // 2^(3+4) l = HorizontalLayout::Builder( - CharLayout('2'), + CharLayout::Builder('2'), VerticalOffsetLayout::Builder( HorizontalLayout::Builder( - CharLayout('3'), - CharLayout('+'), - CharLayout('4')), + CharLayout::Builder('3'), + CharLayout::Builder('+'), + CharLayout::Builder('4')), VerticalOffsetLayoutNode::Type::Superscript)); e = Power::Builder( - Rational(2), + Rational::Builder(2), Addition::Builder( - Rational(3), - Rational(4))); + Rational::Builder(3), + Rational::Builder(4))); assert_parsed_layout_is(l, e); // log_3(2) HorizontalLayout l1 = HorizontalLayout::Builder(); - l1.addChildAtIndex(CharLayout('l'), l1.numberOfChildren(), l1.numberOfChildren(), nullptr); - l1.addChildAtIndex(CharLayout('o'), l1.numberOfChildren(), l1.numberOfChildren(), nullptr); - l1.addChildAtIndex(CharLayout('g'), l1.numberOfChildren(), l1.numberOfChildren(), nullptr); - l1.addChildAtIndex(VerticalOffsetLayout::Builder(CharLayout('3'), VerticalOffsetLayoutNode::Type::Subscript), l1.numberOfChildren(), l1.numberOfChildren(), nullptr); + l1.addChildAtIndex(CharLayout::Builder('l'), l1.numberOfChildren(), l1.numberOfChildren(), nullptr); + l1.addChildAtIndex(CharLayout::Builder('o'), l1.numberOfChildren(), l1.numberOfChildren(), nullptr); + l1.addChildAtIndex(CharLayout::Builder('g'), l1.numberOfChildren(), l1.numberOfChildren(), nullptr); + l1.addChildAtIndex(VerticalOffsetLayout::Builder(CharLayout::Builder('3'), VerticalOffsetLayoutNode::Type::Subscript), l1.numberOfChildren(), l1.numberOfChildren(), nullptr); l1.addChildAtIndex(LeftParenthesisLayout::Builder(), l1.numberOfChildren(), l1.numberOfChildren(), nullptr); - l1.addChildAtIndex(CharLayout('2'), l1.numberOfChildren(), l1.numberOfChildren(), nullptr); + l1.addChildAtIndex(CharLayout::Builder('2'), l1.numberOfChildren(), l1.numberOfChildren(), nullptr); l1.addChildAtIndex(RightParenthesisLayout::Builder(), l1.numberOfChildren(), l1.numberOfChildren(), nullptr); l = l1; e = Logarithm::Builder( - Rational(2), - Rational(3)); + Rational::Builder(2), + Rational::Builder(3)); assert_parsed_layout_is(l, e); // root(5,3) l = NthRootLayout::Builder( - CharLayout('5'), - CharLayout('3')); - e = NthRoot::Builder(Rational(5), Rational(3)); + CharLayout::Builder('5'), + CharLayout::Builder('3')); + e = NthRoot::Builder(Rational::Builder(5), Rational::Builder(3)); assert_parsed_layout_is(l, e); // int(7, x, 4, 5) l = IntegralLayout::Builder( - CharLayout('7'), - CharLayout('x'), - CharLayout('4'), - CharLayout('5')); + CharLayout::Builder('7'), + CharLayout::Builder('x'), + CharLayout::Builder('4'), + CharLayout::Builder('5')); e = Integral::Builder( - Rational(7), - Symbol('x'), - Rational(4), - Rational(5)); + Rational::Builder(7), + Symbol::Builder('x'), + Rational::Builder(4), + Rational::Builder(5)); assert_parsed_layout_is(l, e); // 2^2 ! l = HorizontalLayout::Builder( - CharLayout('2'), + CharLayout::Builder('2'), VerticalOffsetLayout::Builder( - CharLayout('2'), + CharLayout::Builder('2'), VerticalOffsetLayoutNode::Type::Superscript), - CharLayout('!')); + CharLayout::Builder('!')); e = Factorial::Builder( Power::Builder( - Rational(2), - Rational(2))); + Rational::Builder(2), + Rational::Builder(2))); assert_parsed_layout_is(l, e); // 5* 6/(7+5) *3 l = HorizontalLayout::Builder( - CharLayout('5'), + CharLayout::Builder('5'), FractionLayout::Builder( - CharLayout('6'), + CharLayout::Builder('6'), HorizontalLayout::Builder( - CharLayout('7'), - CharLayout('+'), - CharLayout('5'))), - CharLayout('3')); + CharLayout::Builder('7'), + CharLayout::Builder('+'), + CharLayout::Builder('5'))), + CharLayout::Builder('3')); e = Multiplication::Builder( - Rational(5), + Rational::Builder(5), Division::Builder( - Rational(6), + Rational::Builder(6), Addition::Builder( - Rational(7), - Rational(5))), - Rational(3)); + Rational::Builder(7), + Rational::Builder(5))), + Rational::Builder(3)); assert_parsed_layout_is(l, e); // [[3^2!, 7][4,5] l = MatrixLayout::Builder( HorizontalLayout::Builder( - CharLayout('3'), + CharLayout::Builder('3'), VerticalOffsetLayout::Builder( - CharLayout('2'), + CharLayout::Builder('2'), VerticalOffsetLayoutNode::Type::Superscript), - CharLayout('!')), - CharLayout('7'), - CharLayout('4'), - CharLayout('5')); + CharLayout::Builder('!')), + CharLayout::Builder('7'), + CharLayout::Builder('4'), + CharLayout::Builder('5')); Matrix m = BuildOneChildMatrix( Factorial::Builder( Power::Builder( - Rational(3), - Rational(2)))); - m.addChildAtIndexInPlace(Rational(7), 1, 1); - m.addChildAtIndexInPlace(Rational(4), 2, 2); - m.addChildAtIndexInPlace(Rational(5), 3, 3); + Rational::Builder(3), + Rational::Builder(2)))); + m.addChildAtIndexInPlace(Rational::Builder(7), 1, 1); + m.addChildAtIndexInPlace(Rational::Builder(4), 2, 2); + m.addChildAtIndexInPlace(Rational::Builder(5), 3, 3); m.setDimensions(2,2); e = m; assert_parsed_layout_is(l, e); // 2^det([[3!, 7][4,5]) l = HorizontalLayout::Builder( - CharLayout('2'), + CharLayout::Builder('2'), VerticalOffsetLayout::Builder( MatrixLayout::Builder( HorizontalLayout::Builder( - CharLayout('3'), - CharLayout('!')), - CharLayout('7'), - CharLayout('4'), - CharLayout('5')), + CharLayout::Builder('3'), + CharLayout::Builder('!')), + CharLayout::Builder('7'), + CharLayout::Builder('4'), + CharLayout::Builder('5')), VerticalOffsetLayoutNode::Type::Superscript)); m = BuildOneChildMatrix( Factorial::Builder( - Rational(3))); - m.addChildAtIndexInPlace(Rational(7), 1, 1); - m.addChildAtIndexInPlace(Rational(4), 2, 2); - m.addChildAtIndexInPlace(Rational(5), 3, 3); + Rational::Builder(3))); + m.addChildAtIndexInPlace(Rational::Builder(7), 1, 1); + m.addChildAtIndexInPlace(Rational::Builder(4), 2, 2); + m.addChildAtIndexInPlace(Rational::Builder(5), 3, 3); m.setDimensions(2,2); - e = Power::Builder(Rational(2), m); + e = Power::Builder(Rational::Builder(2), m); assert_parsed_layout_is(l, e); // 2e^3 l = HorizontalLayout::Builder( - CharLayout('2'), - CharLayout(Ion::Charset::Exponential), + CharLayout::Builder('2'), + CharLayout::Builder(Ion::Charset::Exponential), VerticalOffsetLayout::Builder( - CharLayout('3'), + CharLayout::Builder('3'), VerticalOffsetLayoutNode::Type::Superscript)); - e = Multiplication::Builder(Rational(2),Power::Builder(Constant(Ion::Charset::Exponential),Parenthesis::Builder(Rational(3)))); - assert_parsed_expression_is("2X^(3)", Multiplication::Builder(Rational(2),Power::Builder(Constant(Ion::Charset::Exponential),Parenthesis::Builder(Rational(3))))); + e = Multiplication::Builder(Rational::Builder(2),Power::Builder(Constant::Builder(Ion::Charset::Exponential),Parenthesis::Builder(Rational::Builder(3)))); + assert_parsed_expression_is("2X^(3)", Multiplication::Builder(Rational::Builder(2),Power::Builder(Constant::Builder(Ion::Charset::Exponential),Parenthesis::Builder(Rational::Builder(3))))); assert_parsed_layout_is(l, e); } diff --git a/poincare/test/number.cpp b/poincare/test/number.cpp index 5bdcb2316..078ced52d 100644 --- a/poincare/test/number.cpp +++ b/poincare/test/number.cpp @@ -12,27 +12,27 @@ using namespace Poincare; QUIZ_CASE(poincare_number_parser) { // Integer - assert_parsed_expression_is("123456789012345678765434567", Rational("123456789012345678765434567")); - assert_parsed_expression_is(MaxIntegerString(), Rational(MaxIntegerString())); + assert_parsed_expression_is("123456789012345678765434567", Rational::Builder("123456789012345678765434567")); + assert_parsed_expression_is(MaxIntegerString(), Rational::Builder(MaxIntegerString())); // Integer parsed in Decimal because they overflow Integer - assert_parsed_expression_is(OverflowedIntegerString(), Decimal(Integer("17976931348623"), 308)); - assert_parsed_expression_is("179769313486235590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216", Decimal(Integer("17976931348624"), 308)); + assert_parsed_expression_is(OverflowedIntegerString(), Decimal::Builder(Integer("17976931348623"), 308)); + assert_parsed_expression_is("179769313486235590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216", Decimal::Builder(Integer("17976931348624"), 308)); // Decimal with rounding when digits are above 14 - assert_parsed_expression_is("0.0000012345678901234", Decimal(Integer("12345678901234"), -6)); - assert_parsed_expression_is("0.00000123456789012345", Decimal(Integer("12345678901235"), -6)); - assert_parsed_expression_is("0.00000123456789012341", Decimal(Integer("12345678901234"), -6)); - assert_parsed_expression_is("1234567890123.4", Decimal(Integer("12345678901234"), 12)); - assert_parsed_expression_is("123456789012345.2", Decimal(Integer("12345678901235"), 14)); - assert_parsed_expression_is("123456789012341.2", Decimal(Integer("12345678901234"), 14)); - assert_parsed_expression_is("12.34567", Decimal(Integer("1234567"), 1)); + assert_parsed_expression_is("0.0000012345678901234", Decimal::Builder(Integer("12345678901234"), -6)); + assert_parsed_expression_is("0.00000123456789012345", Decimal::Builder(Integer("12345678901235"), -6)); + assert_parsed_expression_is("0.00000123456789012341", Decimal::Builder(Integer("12345678901234"), -6)); + assert_parsed_expression_is("1234567890123.4", Decimal::Builder(Integer("12345678901234"), 12)); + assert_parsed_expression_is("123456789012345.2", Decimal::Builder(Integer("12345678901235"), 14)); + assert_parsed_expression_is("123456789012341.2", Decimal::Builder(Integer("12345678901234"), 14)); + assert_parsed_expression_is("12.34567", Decimal::Builder(Integer("1234567"), 1)); // Infinity - assert_parsed_expression_is("23E1000", Infinity(false)); - assert_parsed_expression_is("2.3E1000", Decimal(Integer(23), 1000)); + assert_parsed_expression_is("23E1000", Infinity::Builder(false)); + assert_parsed_expression_is("2.3E1000", Decimal::Builder(Integer(23), 1000)); // Zero - assert_parsed_expression_is("0.23E-1000", Decimal(Integer(0), 0)); - assert_parsed_expression_is("0.23E-999", Decimal(Integer(23), -1000)); + assert_parsed_expression_is("0.23E-1000", Decimal::Builder(Integer(0), 0)); + assert_parsed_expression_is("0.23E-999", Decimal::Builder(Integer(23), -1000)); } diff --git a/poincare/test/parentheses_layout.cpp b/poincare/test/parentheses_layout.cpp index 31cb61069..1cb82c0d3 100644 --- a/poincare/test/parentheses_layout.cpp +++ b/poincare/test/parentheses_layout.cpp @@ -16,16 +16,16 @@ QUIZ_CASE(poincare_parenthesis_layout_size) { LeftParenthesisLayout leftPar = LeftParenthesisLayout::Builder(); RightParenthesisLayout rightPar = RightParenthesisLayout::Builder(); layout.addChildAtIndex(leftPar, 0, 0, nullptr); - layout.addChildAtIndex(CharLayout('2'), 1, 1, nullptr); - layout.addChildAtIndex(CharLayout('+'), 2, 2, nullptr); + layout.addChildAtIndex(CharLayout::Builder('2'), 1, 1, nullptr); + layout.addChildAtIndex(CharLayout::Builder('+'), 2, 2, nullptr); layout.addChildAtIndex(LeftParenthesisLayout::Builder(), 3, 3, nullptr); layout.addChildAtIndex(FractionLayout::Builder( - CharLayout('3'), - CharLayout('4')), + CharLayout::Builder('3'), + CharLayout::Builder('4')), 4, 4, nullptr); layout.addChildAtIndex(RightParenthesisLayout::Builder(), 4, 4, nullptr); - layout.addChildAtIndex(CharLayout('6'), 5, 5, nullptr); + layout.addChildAtIndex(CharLayout::Builder('6'), 5, 5, nullptr); layout.addChildAtIndex(rightPar, 7, 7, nullptr); - layout.addChildAtIndex(CharLayout('1'), 8, 8, nullptr); + layout.addChildAtIndex(CharLayout::Builder('1'), 8, 8, nullptr); quiz_assert(leftPar.layoutSize().height() == rightPar.layoutSize().height()); } diff --git a/poincare/test/parser.cpp b/poincare/test/parser.cpp index f8f9cff22..2c50972f9 100644 --- a/poincare/test/parser.cpp +++ b/poincare/test/parser.cpp @@ -84,18 +84,18 @@ QUIZ_CASE(poincare_parser_parse_numbers) { assert_pool_size(initialPoolSize); // Parse digits - assert_parsed_expression_is("0", Rational(0)); - assert_parsed_expression_is("0.1", Decimal(0.1)); - assert_parsed_expression_is("1.", Rational(1)); - assert_parsed_expression_is(".1", Decimal(0.1)); - assert_parsed_expression_is("0E2", Decimal(0.0)); - assert_parsed_expression_is("0.1E2", Decimal(10.0)); - assert_parsed_expression_is("1.E2", Decimal(100.0)); - assert_parsed_expression_is(".1E2", Decimal(10.0)); - assert_parsed_expression_is("0E-2", Decimal(0.0)); - assert_parsed_expression_is("0.1E-2", Decimal(0.001)); - assert_parsed_expression_is("1.E-2", Decimal(0.01)); - assert_parsed_expression_is(".1E-2", Decimal(0.001)); + assert_parsed_expression_is("0", Rational::Builder(0)); + assert_parsed_expression_is("0.1", Decimal::Builder(0.1)); + assert_parsed_expression_is("1.", Rational::Builder(1)); + assert_parsed_expression_is(".1", Decimal::Builder(0.1)); + assert_parsed_expression_is("0E2", Decimal::Builder(0.0)); + assert_parsed_expression_is("0.1E2", Decimal::Builder(10.0)); + assert_parsed_expression_is("1.E2", Decimal::Builder(100.0)); + assert_parsed_expression_is(".1E2", Decimal::Builder(10.0)); + assert_parsed_expression_is("0E-2", Decimal::Builder(0.0)); + assert_parsed_expression_is("0.1E-2", Decimal::Builder(0.001)); + assert_parsed_expression_is("1.E-2", Decimal::Builder(0.01)); + assert_parsed_expression_is(".1E-2", Decimal::Builder(0.001)); } QUIZ_CASE(poincare_parser_memory_exhaustion) { @@ -123,66 +123,66 @@ QUIZ_CASE(poincare_parser_memory_exhaustion) { } QUIZ_CASE(poincare_parser_parse) { - assert_parsed_expression_is("1", Rational(1)); - assert_parsed_expression_is("(1)", Parenthesis::Builder(Rational(1))); - assert_parsed_expression_is("((1))", Parenthesis::Builder((Expression)Parenthesis::Builder(Rational(1)))); - assert_parsed_expression_is("1+2", Addition::Builder(Rational(1),Rational(2))); - assert_parsed_expression_is("(1)+2", Addition::Builder(Parenthesis::Builder(Rational(1)),Rational(2))); - assert_parsed_expression_is("(1+2)", Parenthesis::Builder(Addition::Builder(Rational(1),Rational(2)))); - assert_parsed_expression_is("1+2+3", Addition::Builder(Addition::Builder(Rational(1),Rational(2)),Rational(3))); - assert_parsed_expression_is("1+2+(3+4)", Addition::Builder(Addition::Builder(Rational(1),Rational(2)),Parenthesis::Builder(Addition::Builder(Rational(3),Rational(4))))); - assert_parsed_expression_is("1*2", Multiplication::Builder(Rational(1),Rational(2))); - assert_parsed_expression_is("1*2*3", Multiplication::Builder(Multiplication::Builder(Rational(1),Rational(2)),Rational(3))); - assert_parsed_expression_is("1+2*3", Addition::Builder(Rational(1), Multiplication::Builder(Rational(2), Rational(3)))); - assert_parsed_expression_is("1/2", Division::Builder(Rational(1),Rational(2))); - assert_parsed_expression_is("(1/2)", Parenthesis::Builder(Division::Builder(Rational(1),Rational(2)))); - assert_parsed_expression_is("1/2/3", Division::Builder(Division::Builder(Rational(1),Rational(2)),Rational(3))); - assert_parsed_expression_is("1/2*3", Multiplication::Builder(Division::Builder(Rational(1),Rational(2)),Rational(3))); - assert_parsed_expression_is("(1/2*3)", Parenthesis::Builder(Multiplication::Builder(Division::Builder(Rational(1),Rational(2)),Rational(3)))); - assert_parsed_expression_is("1*2/3", Multiplication::Builder(Rational(1),Division::Builder(Rational(2),Rational(3)))); - assert_parsed_expression_is("(1*2/3)", Parenthesis::Builder(Multiplication::Builder(Rational(1),Division::Builder(Rational(2),Rational(3))))); - assert_parsed_expression_is("(1/2/3)", Parenthesis::Builder(Division::Builder(Division::Builder(Rational(1),Rational(2)),Rational(3)))); - assert_parsed_expression_is("1^2", Power::Builder(Rational(1),Rational(2))); - assert_parsed_expression_is("1^2^3", Power::Builder(Rational(1),Power::Builder(Rational(2),Rational(3)))); - assert_parsed_expression_is("1=2", Equal(Rational(1),Rational(2))); + assert_parsed_expression_is("1", Rational::Builder(1)); + assert_parsed_expression_is("(1)", Parenthesis::Builder(Rational::Builder(1))); + assert_parsed_expression_is("((1))", Parenthesis::Builder((Expression)Parenthesis::Builder(Rational::Builder(1)))); + assert_parsed_expression_is("1+2", Addition::Builder(Rational::Builder(1),Rational::Builder(2))); + assert_parsed_expression_is("(1)+2", Addition::Builder(Parenthesis::Builder(Rational::Builder(1)),Rational::Builder(2))); + assert_parsed_expression_is("(1+2)", Parenthesis::Builder(Addition::Builder(Rational::Builder(1),Rational::Builder(2)))); + assert_parsed_expression_is("1+2+3", Addition::Builder(Addition::Builder(Rational::Builder(1),Rational::Builder(2)),Rational::Builder(3))); + assert_parsed_expression_is("1+2+(3+4)", Addition::Builder(Addition::Builder(Rational::Builder(1),Rational::Builder(2)),Parenthesis::Builder(Addition::Builder(Rational::Builder(3),Rational::Builder(4))))); + assert_parsed_expression_is("1*2", Multiplication::Builder(Rational::Builder(1),Rational::Builder(2))); + assert_parsed_expression_is("1*2*3", Multiplication::Builder(Multiplication::Builder(Rational::Builder(1),Rational::Builder(2)),Rational::Builder(3))); + assert_parsed_expression_is("1+2*3", Addition::Builder(Rational::Builder(1), Multiplication::Builder(Rational::Builder(2), Rational::Builder(3)))); + assert_parsed_expression_is("1/2", Division::Builder(Rational::Builder(1),Rational::Builder(2))); + assert_parsed_expression_is("(1/2)", Parenthesis::Builder(Division::Builder(Rational::Builder(1),Rational::Builder(2)))); + assert_parsed_expression_is("1/2/3", Division::Builder(Division::Builder(Rational::Builder(1),Rational::Builder(2)),Rational::Builder(3))); + assert_parsed_expression_is("1/2*3", Multiplication::Builder(Division::Builder(Rational::Builder(1),Rational::Builder(2)),Rational::Builder(3))); + assert_parsed_expression_is("(1/2*3)", Parenthesis::Builder(Multiplication::Builder(Division::Builder(Rational::Builder(1),Rational::Builder(2)),Rational::Builder(3)))); + assert_parsed_expression_is("1*2/3", Multiplication::Builder(Rational::Builder(1),Division::Builder(Rational::Builder(2),Rational::Builder(3)))); + assert_parsed_expression_is("(1*2/3)", Parenthesis::Builder(Multiplication::Builder(Rational::Builder(1),Division::Builder(Rational::Builder(2),Rational::Builder(3))))); + assert_parsed_expression_is("(1/2/3)", Parenthesis::Builder(Division::Builder(Division::Builder(Rational::Builder(1),Rational::Builder(2)),Rational::Builder(3)))); + assert_parsed_expression_is("1^2", Power::Builder(Rational::Builder(1),Rational::Builder(2))); + assert_parsed_expression_is("1^2^3", Power::Builder(Rational::Builder(1),Power::Builder(Rational::Builder(2),Rational::Builder(3)))); + assert_parsed_expression_is("1=2", Equal::Builder(Rational::Builder(1),Rational::Builder(2))); assert_raises_parsing_error("=5"); assert_raises_parsing_error("1=2=3"); - assert_parsed_expression_is("-1", Opposite::Builder(Rational(1))); - assert_parsed_expression_is("(-1)", Parenthesis::Builder(Opposite::Builder(Rational(1)))); - assert_parsed_expression_is("1-2", Subtraction::Builder(Rational(1),Rational(2))); - assert_parsed_expression_is("-1-2", Subtraction::Builder(Opposite::Builder(Rational(1)),Rational(2))); - assert_parsed_expression_is("1-2-3", Subtraction::Builder(Subtraction::Builder(Rational(1),Rational(2)),Rational(3))); - assert_parsed_expression_is("(1-2)", Parenthesis::Builder(Subtraction::Builder(Rational(1),Rational(2)))); - assert_parsed_expression_is("1+-2", Addition::Builder(Rational(1),Opposite::Builder(Rational(2)))); - assert_parsed_expression_is("--1", Opposite::Builder((Expression)Opposite::Builder(Rational(1)))); - assert_parsed_expression_is("(1+2)-3", Subtraction::Builder(Parenthesis::Builder(Addition::Builder(Rational(1),Rational(2))),Rational(3))); - assert_parsed_expression_is("(2*-3)", Parenthesis::Builder(Multiplication::Builder(Rational(2),Opposite::Builder(Rational(3))))); - assert_parsed_expression_is("1^(2)-3", Subtraction::Builder(Power::Builder(Rational(1),Parenthesis::Builder(Rational(2))),Rational(3))); - assert_parsed_expression_is("1^2-3", Subtraction::Builder(Power::Builder(Rational(1),Rational(2)),Rational(3))); - assert_parsed_expression_is("2^-3", Power::Builder(Rational(2),Opposite::Builder(Rational(3)))); - assert_parsed_expression_is("2--2+-1", Addition::Builder(Subtraction::Builder(Rational(2),Opposite::Builder(Rational(2))),Opposite::Builder(Rational(1)))); - assert_parsed_expression_is("2--2*-1", Subtraction::Builder(Rational(2),Opposite::Builder(Multiplication::Builder(Rational(2),Opposite::Builder(Rational(1)))))); - assert_parsed_expression_is("-1^2", Opposite::Builder(Power::Builder(Rational(1),Rational(2)))); - assert_parsed_expression_is("2/-3/-4", Division::Builder(Division::Builder(Rational(2),Opposite::Builder(Rational(3))),Opposite::Builder(Rational(4)))); - assert_parsed_expression_is("1*2-3*4", Subtraction::Builder(Multiplication::Builder(Rational(1),Rational(2)),Multiplication::Builder(Rational(3),Rational(4)))); - assert_parsed_expression_is("-1*2", Opposite::Builder(Multiplication::Builder(Rational(1), Rational(2)))); - assert_parsed_expression_is("1!", Factorial::Builder(Rational(1))); - assert_parsed_expression_is("1+2!", Addition::Builder(Rational(1),Factorial::Builder(Rational(2)))); - assert_parsed_expression_is("1!+2", Addition::Builder(Factorial::Builder(Rational(1)),Rational(2))); - assert_parsed_expression_is("1!+2!", Addition::Builder(Factorial::Builder(Rational(1)),Factorial::Builder(Rational(2)))); - assert_parsed_expression_is("1*2!", Multiplication::Builder(Rational(1),Factorial::Builder(Rational(2)))); - assert_parsed_expression_is("1!*2", Multiplication::Builder(Factorial::Builder(Rational(1)),Rational(2))); - assert_parsed_expression_is("1!*2!", Multiplication::Builder(Factorial::Builder(Rational(1)),Factorial::Builder(Rational(2)))); - assert_parsed_expression_is("1-2!", Subtraction::Builder(Rational(1),Factorial::Builder(Rational(2)))); - assert_parsed_expression_is("1!-2", Subtraction::Builder(Factorial::Builder(Rational(1)),Rational(2))); - assert_parsed_expression_is("1!-2!", Subtraction::Builder(Factorial::Builder(Rational(1)),Factorial::Builder(Rational(2)))); - assert_parsed_expression_is("1/2!", Division::Builder(Rational(1),Factorial::Builder(Rational(2)))); - assert_parsed_expression_is("1!/2", Division::Builder(Factorial::Builder(Rational(1)),Rational(2))); - assert_parsed_expression_is("1!/2!", Division::Builder(Factorial::Builder(Rational(1)),Factorial::Builder(Rational(2)))); - assert_parsed_expression_is("1^2!", Power::Builder(Rational(1),Factorial::Builder(Rational(2)))); - assert_parsed_expression_is("1!^2", Power::Builder(Factorial::Builder(Rational(1)),Rational(2))); - assert_parsed_expression_is("1!^2!", Power::Builder(Factorial::Builder(Rational(1)),Factorial::Builder(Rational(2)))); - assert_parsed_expression_is("(1)!", Factorial::Builder(Parenthesis::Builder(Rational(1)))); + assert_parsed_expression_is("-1", Opposite::Builder(Rational::Builder(1))); + assert_parsed_expression_is("(-1)", Parenthesis::Builder(Opposite::Builder(Rational::Builder(1)))); + assert_parsed_expression_is("1-2", Subtraction::Builder(Rational::Builder(1),Rational::Builder(2))); + assert_parsed_expression_is("-1-2", Subtraction::Builder(Opposite::Builder(Rational::Builder(1)),Rational::Builder(2))); + assert_parsed_expression_is("1-2-3", Subtraction::Builder(Subtraction::Builder(Rational::Builder(1),Rational::Builder(2)),Rational::Builder(3))); + assert_parsed_expression_is("(1-2)", Parenthesis::Builder(Subtraction::Builder(Rational::Builder(1),Rational::Builder(2)))); + assert_parsed_expression_is("1+-2", Addition::Builder(Rational::Builder(1),Opposite::Builder(Rational::Builder(2)))); + assert_parsed_expression_is("--1", Opposite::Builder((Expression)Opposite::Builder(Rational::Builder(1)))); + assert_parsed_expression_is("(1+2)-3", Subtraction::Builder(Parenthesis::Builder(Addition::Builder(Rational::Builder(1),Rational::Builder(2))),Rational::Builder(3))); + assert_parsed_expression_is("(2*-3)", Parenthesis::Builder(Multiplication::Builder(Rational::Builder(2),Opposite::Builder(Rational::Builder(3))))); + assert_parsed_expression_is("1^(2)-3", Subtraction::Builder(Power::Builder(Rational::Builder(1),Parenthesis::Builder(Rational::Builder(2))),Rational::Builder(3))); + assert_parsed_expression_is("1^2-3", Subtraction::Builder(Power::Builder(Rational::Builder(1),Rational::Builder(2)),Rational::Builder(3))); + assert_parsed_expression_is("2^-3", Power::Builder(Rational::Builder(2),Opposite::Builder(Rational::Builder(3)))); + assert_parsed_expression_is("2--2+-1", Addition::Builder(Subtraction::Builder(Rational::Builder(2),Opposite::Builder(Rational::Builder(2))),Opposite::Builder(Rational::Builder(1)))); + assert_parsed_expression_is("2--2*-1", Subtraction::Builder(Rational::Builder(2),Opposite::Builder(Multiplication::Builder(Rational::Builder(2),Opposite::Builder(Rational::Builder(1)))))); + assert_parsed_expression_is("-1^2", Opposite::Builder(Power::Builder(Rational::Builder(1),Rational::Builder(2)))); + assert_parsed_expression_is("2/-3/-4", Division::Builder(Division::Builder(Rational::Builder(2),Opposite::Builder(Rational::Builder(3))),Opposite::Builder(Rational::Builder(4)))); + assert_parsed_expression_is("1*2-3*4", Subtraction::Builder(Multiplication::Builder(Rational::Builder(1),Rational::Builder(2)),Multiplication::Builder(Rational::Builder(3),Rational::Builder(4)))); + assert_parsed_expression_is("-1*2", Opposite::Builder(Multiplication::Builder(Rational::Builder(1), Rational::Builder(2)))); + assert_parsed_expression_is("1!", Factorial::Builder(Rational::Builder(1))); + assert_parsed_expression_is("1+2!", Addition::Builder(Rational::Builder(1),Factorial::Builder(Rational::Builder(2)))); + assert_parsed_expression_is("1!+2", Addition::Builder(Factorial::Builder(Rational::Builder(1)),Rational::Builder(2))); + assert_parsed_expression_is("1!+2!", Addition::Builder(Factorial::Builder(Rational::Builder(1)),Factorial::Builder(Rational::Builder(2)))); + assert_parsed_expression_is("1*2!", Multiplication::Builder(Rational::Builder(1),Factorial::Builder(Rational::Builder(2)))); + assert_parsed_expression_is("1!*2", Multiplication::Builder(Factorial::Builder(Rational::Builder(1)),Rational::Builder(2))); + assert_parsed_expression_is("1!*2!", Multiplication::Builder(Factorial::Builder(Rational::Builder(1)),Factorial::Builder(Rational::Builder(2)))); + assert_parsed_expression_is("1-2!", Subtraction::Builder(Rational::Builder(1),Factorial::Builder(Rational::Builder(2)))); + assert_parsed_expression_is("1!-2", Subtraction::Builder(Factorial::Builder(Rational::Builder(1)),Rational::Builder(2))); + assert_parsed_expression_is("1!-2!", Subtraction::Builder(Factorial::Builder(Rational::Builder(1)),Factorial::Builder(Rational::Builder(2)))); + assert_parsed_expression_is("1/2!", Division::Builder(Rational::Builder(1),Factorial::Builder(Rational::Builder(2)))); + assert_parsed_expression_is("1!/2", Division::Builder(Factorial::Builder(Rational::Builder(1)),Rational::Builder(2))); + assert_parsed_expression_is("1!/2!", Division::Builder(Factorial::Builder(Rational::Builder(1)),Factorial::Builder(Rational::Builder(2)))); + assert_parsed_expression_is("1^2!", Power::Builder(Rational::Builder(1),Factorial::Builder(Rational::Builder(2)))); + assert_parsed_expression_is("1!^2", Power::Builder(Factorial::Builder(Rational::Builder(1)),Rational::Builder(2))); + assert_parsed_expression_is("1!^2!", Power::Builder(Factorial::Builder(Rational::Builder(1)),Factorial::Builder(Rational::Builder(2)))); + assert_parsed_expression_is("(1)!", Factorial::Builder(Parenthesis::Builder(Rational::Builder(1)))); assert_raises_parsing_error("1+"); assert_raises_parsing_error(")"); assert_raises_parsing_error(")("); @@ -215,13 +215,13 @@ Matrix BuildMatrix(int rows, int columns, Expression entries[]) { } QUIZ_CASE(poincare_parser_matrices) { - Expression m1[] = {Rational(1)}; + Expression m1[] = {Rational::Builder(1)}; assert_parsed_expression_is("[[1]]", BuildMatrix(1,1,m1)); - Expression m2[] = {Rational(1),Rational(2),Rational(3)}; + Expression m2[] = {Rational::Builder(1),Rational::Builder(2),Rational::Builder(3)}; assert_parsed_expression_is("[[1,2,3]]", BuildMatrix(1,3,m2)); - Expression m3[] = {Rational(1),Rational(2),Rational(3),Rational(4),Rational(5),Rational(6)}; + Expression m3[] = {Rational::Builder(1),Rational::Builder(2),Rational::Builder(3),Rational::Builder(4),Rational::Builder(5),Rational::Builder(6)}; assert_parsed_expression_is("[[1,2,3][4,5,6]]", BuildMatrix(2,3,m3)); - Expression m4[] = {Rational(1), BuildMatrix(1,1,m1)}; + Expression m4[] = {Rational::Builder(1), BuildMatrix(1,1,m1)}; assert_parsed_expression_is("[[1,[[1]]]]", BuildMatrix(1,2,m4)); assert_raises_parsing_error("["); assert_raises_parsing_error("]"); @@ -241,105 +241,105 @@ QUIZ_CASE(poincare_parser_matrices) { QUIZ_CASE(poincare_parser_symbols_and_functions) { // User-defined symbols - assert_parsed_expression_is("a", Symbol("a", 1)); - assert_parsed_expression_is("x", Symbol("x", 1)); - assert_parsed_expression_is("toot", Symbol("toot", 4)); - assert_parsed_expression_is("toto_", Symbol("toto_", 5)); - assert_parsed_expression_is("t_toto", Symbol("t_toto", 6)); - assert_parsed_expression_is("tot12", Symbol("tot12", 5)); - assert_parsed_expression_is("TOto", Symbol("TOto", 4)); - assert_parsed_expression_is("TO12_Or", Symbol("TO12_Or", 7)); + assert_parsed_expression_is("a", Symbol::Builder("a", 1)); + assert_parsed_expression_is("x", Symbol::Builder("x", 1)); + assert_parsed_expression_is("toot", Symbol::Builder("toot", 4)); + assert_parsed_expression_is("toto_", Symbol::Builder("toto_", 5)); + assert_parsed_expression_is("t_toto", Symbol::Builder("t_toto", 6)); + assert_parsed_expression_is("tot12", Symbol::Builder("tot12", 5)); + assert_parsed_expression_is("TOto", Symbol::Builder("TOto", 4)); + assert_parsed_expression_is("TO12_Or", Symbol::Builder("TO12_Or", 7)); assert_raises_parsing_error("_a"); assert_raises_parsing_error("abcdefgh"); // User-defined functions - assert_parsed_expression_is("f(x)", Function("f", 1, Symbol("x",1))); - assert_parsed_expression_is("f(1)", Function("f", 1, Rational(1))); - assert_parsed_expression_is("ab12AB_(x)", Function("ab12AB_", 7, Symbol("x",1))); - assert_parsed_expression_is("ab12AB_(1)", Function("ab12AB_", 7, Rational(1))); - assert_parsed_expression_is("f(g(x))", Function("f", 1, Function("g", 1, Symbol("x",1)))); - assert_parsed_expression_is("f(g(1))", Function("f", 1, Function("g", 1, Rational(1)))); - assert_parsed_expression_is("f((1))", Function("f", 1, Parenthesis::Builder(Rational(1)))); + assert_parsed_expression_is("f(x)", Function::Builder("f", 1, Symbol::Builder("x",1))); + assert_parsed_expression_is("f(1)", Function::Builder("f", 1, Rational::Builder(1))); + assert_parsed_expression_is("ab12AB_(x)", Function::Builder("ab12AB_", 7, Symbol::Builder("x",1))); + assert_parsed_expression_is("ab12AB_(1)", Function::Builder("ab12AB_", 7, Rational::Builder(1))); + assert_parsed_expression_is("f(g(x))", Function::Builder("f", 1, Function::Builder("g", 1, Symbol::Builder("x",1)))); + assert_parsed_expression_is("f(g(1))", Function::Builder("f", 1, Function::Builder("g", 1, Rational::Builder(1)))); + assert_parsed_expression_is("f((1))", Function::Builder("f", 1, Parenthesis::Builder(Rational::Builder(1)))); assert_raises_parsing_error("f(1,2)"); assert_raises_parsing_error("f(f)"); assert_raises_parsing_error("abcdefgh(1)"); // Reserved symbols - assert_parsed_expression_is("ans", Symbol("ans", 3)); - assert_parsed_expression_is("I", Constant(Ion::Charset::IComplex)); - assert_parsed_expression_is("P", Constant(Ion::Charset::SmallPi)); - assert_parsed_expression_is("X", Constant(Ion::Charset::Exponential)); - assert_parsed_expression_is(Infinity::Name(), Infinity(false)); - assert_parsed_expression_is(Undefined::Name(), Undefined()); + assert_parsed_expression_is("ans", Symbol::Builder("ans", 3)); + assert_parsed_expression_is("I", Constant::Builder(Ion::Charset::IComplex)); + assert_parsed_expression_is("P", Constant::Builder(Ion::Charset::SmallPi)); + assert_parsed_expression_is("X", Constant::Builder(Ion::Charset::Exponential)); + assert_parsed_expression_is(Infinity::Name(), Infinity::Builder(false)); + assert_parsed_expression_is(Undefined::Name(), Undefined::Builder()); assert_raises_parsing_error("u"); assert_raises_parsing_error("v"); // Reserved functions - assert_parsed_expression_is("acos(1)", ArcCosine::Builder(Rational(1))); - assert_parsed_expression_is("acosh(1)", HyperbolicArcCosine::Builder(Rational(1))); - assert_parsed_expression_is("abs(1)", AbsoluteValue::Builder(Rational(1))); - assert_parsed_expression_is("arg(1)", ComplexArgument::Builder(Rational(1))); - assert_parsed_expression_is("asin(1)", ArcSine::Builder(Rational(1))); - assert_parsed_expression_is("asinh(1)", HyperbolicArcSine::Builder(Rational(1))); - assert_parsed_expression_is("atan(1)", ArcTangent::Builder(Rational(1))); - assert_parsed_expression_is("atanh(1)", HyperbolicArcTangent::Builder(Rational(1))); - assert_parsed_expression_is("binomial(2,1)", BinomialCoefficient::Builder(Rational(2),Rational(1))); - assert_parsed_expression_is("ceil(1)", Ceiling::Builder(Rational(1))); - assert_parsed_expression_is("confidence(1,2)", ConfidenceInterval::Builder(Rational(1),Rational(2))); + assert_parsed_expression_is("acos(1)", ArcCosine::Builder(Rational::Builder(1))); + assert_parsed_expression_is("acosh(1)", HyperbolicArcCosine::Builder(Rational::Builder(1))); + assert_parsed_expression_is("abs(1)", AbsoluteValue::Builder(Rational::Builder(1))); + assert_parsed_expression_is("arg(1)", ComplexArgument::Builder(Rational::Builder(1))); + assert_parsed_expression_is("asin(1)", ArcSine::Builder(Rational::Builder(1))); + assert_parsed_expression_is("asinh(1)", HyperbolicArcSine::Builder(Rational::Builder(1))); + assert_parsed_expression_is("atan(1)", ArcTangent::Builder(Rational::Builder(1))); + assert_parsed_expression_is("atanh(1)", HyperbolicArcTangent::Builder(Rational::Builder(1))); + assert_parsed_expression_is("binomial(2,1)", BinomialCoefficient::Builder(Rational::Builder(2),Rational::Builder(1))); + assert_parsed_expression_is("ceil(1)", Ceiling::Builder(Rational::Builder(1))); + assert_parsed_expression_is("confidence(1,2)", ConfidenceInterval::Builder(Rational::Builder(1),Rational::Builder(2))); assert_raises_parsing_error("diff(1,2,3)"); - assert_parsed_expression_is("diff(1,x,3)", Derivative::Builder(Rational(1),Symbol("x",1),Rational(3))); - assert_parsed_expression_is("dim(1)", MatrixDimension::Builder(Rational(1))); - assert_parsed_expression_is("conj(1)", Conjugate::Builder(Rational(1))); - assert_parsed_expression_is("det(1)", Determinant::Builder(Rational(1))); - assert_parsed_expression_is("cos(1)", Cosine::Builder(Rational(1))); - assert_parsed_expression_is("cosh(1)", HyperbolicCosine::Builder(Rational(1))); - assert_parsed_expression_is("factor(1)", Factor::Builder(Rational(1))); - assert_parsed_expression_is("floor(1)", Floor::Builder(Rational(1))); - assert_parsed_expression_is("frac(1)", FracPart::Builder(Rational(1))); - assert_parsed_expression_is("gcd(1,2)", GreatCommonDivisor::Builder(Rational(1),Rational(2))); - assert_parsed_expression_is("im(1)", ImaginaryPart::Builder(Rational(1))); - assert_parsed_expression_is("int(1,x,2,3)", Integral::Builder(Rational(1),Symbol("x",1),Rational(2),Rational(3))); + assert_parsed_expression_is("diff(1,x,3)", Derivative::Builder(Rational::Builder(1),Symbol::Builder("x",1),Rational::Builder(3))); + assert_parsed_expression_is("dim(1)", MatrixDimension::Builder(Rational::Builder(1))); + assert_parsed_expression_is("conj(1)", Conjugate::Builder(Rational::Builder(1))); + assert_parsed_expression_is("det(1)", Determinant::Builder(Rational::Builder(1))); + assert_parsed_expression_is("cos(1)", Cosine::Builder(Rational::Builder(1))); + assert_parsed_expression_is("cosh(1)", HyperbolicCosine::Builder(Rational::Builder(1))); + assert_parsed_expression_is("factor(1)", Factor::Builder(Rational::Builder(1))); + assert_parsed_expression_is("floor(1)", Floor::Builder(Rational::Builder(1))); + assert_parsed_expression_is("frac(1)", FracPart::Builder(Rational::Builder(1))); + assert_parsed_expression_is("gcd(1,2)", GreatCommonDivisor::Builder(Rational::Builder(1),Rational::Builder(2))); + assert_parsed_expression_is("im(1)", ImaginaryPart::Builder(Rational::Builder(1))); + assert_parsed_expression_is("int(1,x,2,3)", Integral::Builder(Rational::Builder(1),Symbol::Builder("x",1),Rational::Builder(2),Rational::Builder(3))); assert_raises_parsing_error("int(1,2,3,4)"); - assert_parsed_expression_is("inverse(1)", MatrixInverse::Builder(Rational(1))); - assert_parsed_expression_is("lcm(1,2)", LeastCommonMultiple::Builder(Rational(1),Rational(2))); - assert_parsed_expression_is("ln(1)", NaperianLogarithm::Builder(Rational(1))); - assert_parsed_expression_is("log(1)", CommonLogarithm::Builder(Rational(1))); - assert_parsed_expression_is("log(1,2)", Logarithm::Builder(Rational(1),Rational(2))); - assert_parsed_expression_is("log_{2}(1)", Logarithm::Builder(Rational(1),Rational(2))); - assert_parsed_expression_is("permute(2,1)", PermuteCoefficient::Builder(Rational(2),Rational(1))); - assert_parsed_expression_is("prediction95(1,2)", PredictionInterval::Builder(Rational(1),Rational(2))); - assert_parsed_expression_is("prediction(1,2)", SimplePredictionInterval::Builder(Rational(1),Rational(2))); - assert_parsed_expression_is("product(1,n,2,3)", Product::Builder(Rational(1),Symbol("n",1),Rational(2),Rational(3))); + assert_parsed_expression_is("inverse(1)", MatrixInverse::Builder(Rational::Builder(1))); + assert_parsed_expression_is("lcm(1,2)", LeastCommonMultiple::Builder(Rational::Builder(1),Rational::Builder(2))); + assert_parsed_expression_is("ln(1)", NaperianLogarithm::Builder(Rational::Builder(1))); + assert_parsed_expression_is("log(1)", CommonLogarithm::Builder(Rational::Builder(1))); + assert_parsed_expression_is("log(1,2)", Logarithm::Builder(Rational::Builder(1),Rational::Builder(2))); + assert_parsed_expression_is("log_{2}(1)", Logarithm::Builder(Rational::Builder(1),Rational::Builder(2))); + assert_parsed_expression_is("permute(2,1)", PermuteCoefficient::Builder(Rational::Builder(2),Rational::Builder(1))); + assert_parsed_expression_is("prediction95(1,2)", PredictionInterval::Builder(Rational::Builder(1),Rational::Builder(2))); + assert_parsed_expression_is("prediction(1,2)", SimplePredictionInterval::Builder(Rational::Builder(1),Rational::Builder(2))); + assert_parsed_expression_is("product(1,n,2,3)", Product::Builder(Rational::Builder(1),Symbol::Builder("n",1),Rational::Builder(2),Rational::Builder(3))); assert_raises_parsing_error("product(1,2,3,4)"); - assert_parsed_expression_is("quo(1,2)", DivisionQuotient::Builder(Rational(1),Rational(2))); + assert_parsed_expression_is("quo(1,2)", DivisionQuotient::Builder(Rational::Builder(1),Rational::Builder(2))); assert_parsed_expression_is("random()", Random::Builder()); - assert_parsed_expression_is("randint(1,2)", Randint::Builder(Rational(1),Rational(2))); - assert_parsed_expression_is("re(1)", RealPart::Builder(Rational(1))); - assert_parsed_expression_is("rem(1,2)", DivisionRemainder::Builder(Rational(1),Rational(2))); - assert_parsed_expression_is("root(1,2)", NthRoot::Builder(Rational(1),Rational(2))); - assert_parsed_expression_is("round(1,2)", Round::Builder(Rational(1),Rational(2))); - assert_parsed_expression_is("sin(1)", Sine::Builder(Rational(1))); - assert_parsed_expression_is("sinh(1)", HyperbolicSine::Builder(Rational(1))); - assert_parsed_expression_is("sum(1,n,2,3)", Sum::Builder(Rational(1),Symbol("n",1),Rational(2),Rational(3))); + assert_parsed_expression_is("randint(1,2)", Randint::Builder(Rational::Builder(1),Rational::Builder(2))); + assert_parsed_expression_is("re(1)", RealPart::Builder(Rational::Builder(1))); + assert_parsed_expression_is("rem(1,2)", DivisionRemainder::Builder(Rational::Builder(1),Rational::Builder(2))); + assert_parsed_expression_is("root(1,2)", NthRoot::Builder(Rational::Builder(1),Rational::Builder(2))); + assert_parsed_expression_is("round(1,2)", Round::Builder(Rational::Builder(1),Rational::Builder(2))); + assert_parsed_expression_is("sin(1)", Sine::Builder(Rational::Builder(1))); + assert_parsed_expression_is("sinh(1)", HyperbolicSine::Builder(Rational::Builder(1))); + assert_parsed_expression_is("sum(1,n,2,3)", Sum::Builder(Rational::Builder(1),Symbol::Builder("n",1),Rational::Builder(2),Rational::Builder(3))); assert_raises_parsing_error("sum(1,2,3,4)"); - assert_parsed_expression_is("tan(1)", Tangent::Builder(Rational(1))); - assert_parsed_expression_is("tanh(1)", HyperbolicTangent::Builder(Rational(1))); - assert_parsed_expression_is("trace(1)", MatrixTrace::Builder(Rational(1))); - assert_parsed_expression_is("transpose(1)", MatrixTranspose::Builder(Rational(1))); - assert_parsed_expression_is("\x91(1)", SquareRoot::Builder(Rational(1))); + assert_parsed_expression_is("tan(1)", Tangent::Builder(Rational::Builder(1))); + assert_parsed_expression_is("tanh(1)", HyperbolicTangent::Builder(Rational::Builder(1))); + assert_parsed_expression_is("trace(1)", MatrixTrace::Builder(Rational::Builder(1))); + assert_parsed_expression_is("transpose(1)", MatrixTranspose::Builder(Rational::Builder(1))); + assert_parsed_expression_is("\x91(1)", SquareRoot::Builder(Rational::Builder(1))); assert_raises_parsing_error("cos(1,2)"); assert_raises_parsing_error("log(1,2,3)"); } QUIZ_CASE(poincare_parser_parse_store) { - assert_parsed_expression_is("1>a", Store::Builder(Rational(1),Symbol("a",1))); - assert_parsed_expression_is("1>e", Store::Builder(Rational(1),Symbol("e",1))); - assert_parsed_expression_is("1>f(x)", Store::Builder(Rational(1),Function("f",1,Symbol("x",1)))); - assert_parsed_expression_is("x>f(x)", Store::Builder(Symbol("x",1),Function("f",1,Symbol("x",1)))); - assert_parsed_expression_is("n>f(x)", Store::Builder(Symbol("n",1),Function("f",1,Symbol("x",1)))); - Expression m0[] = {Symbol('x')}; - assert_parsed_expression_is("[[x]]>f(x)", Store::Builder(BuildMatrix(1,1,m0), Function("f", 1, Symbol('x')))); + assert_parsed_expression_is("1>a", Store::Builder(Rational::Builder(1),Symbol::Builder("a",1))); + assert_parsed_expression_is("1>e", Store::Builder(Rational::Builder(1),Symbol::Builder("e",1))); + assert_parsed_expression_is("1>f(x)", Store::Builder(Rational::Builder(1),Function::Builder("f",1,Symbol::Builder("x",1)))); + assert_parsed_expression_is("x>f(x)", Store::Builder(Symbol::Builder("x",1),Function::Builder("f",1,Symbol::Builder("x",1)))); + assert_parsed_expression_is("n>f(x)", Store::Builder(Symbol::Builder("n",1),Function::Builder("f",1,Symbol::Builder("x",1)))); + Expression m0[] = {Symbol::Builder('x')}; + assert_parsed_expression_is("[[x]]>f(x)", Store::Builder(BuildMatrix(1,1,m0), Function::Builder("f", 1, Symbol::Builder('x')))); assert_raises_parsing_error("a>b>c"); assert_raises_parsing_error("1>2"); assert_raises_parsing_error("1>"); @@ -369,26 +369,26 @@ QUIZ_CASE(poincare_parser_parse_store) { QUIZ_CASE(poincare_parser_implicit_multiplication) { assert_raises_parsing_error(".1.2"); assert_raises_parsing_error("1 2"); - assert_parsed_expression_is("1x", Multiplication::Builder(Rational(1),Symbol("x", 1))); - assert_parsed_expression_is("1ans", Multiplication::Builder(Rational(1),Symbol("ans", 3))); - assert_parsed_expression_is("x1", Symbol("x1", 2)); - assert_parsed_expression_is("1x+2", Addition::Builder(Multiplication::Builder(Rational(1),Symbol("x", 1)),Rational(2))); - assert_parsed_expression_is("1P", Multiplication::Builder(Rational(1),Constant(Ion::Charset::SmallPi))); - assert_parsed_expression_is("1x-2", Subtraction::Builder(Multiplication::Builder(Rational(1),Symbol("x", 1)),Rational(2))); - assert_parsed_expression_is("-1x", Opposite::Builder(Multiplication::Builder(Rational(1),Symbol("x", 1)))); - assert_parsed_expression_is("2*1x", Multiplication::Builder(Rational(2),Multiplication::Builder(Rational(1),Symbol("x", 1)))); - assert_parsed_expression_is("2^1x", Multiplication::Builder(Power::Builder(Rational(2),Rational(1)),Symbol("x", 1))); - assert_parsed_expression_is("1x^2", Multiplication::Builder(Rational(1),Power::Builder(Symbol("x", 1),Rational(2)))); - assert_parsed_expression_is("2/1x", Division::Builder(Rational(2),Multiplication::Builder(Rational(1),Symbol("x", 1)))); - assert_parsed_expression_is("1x/2", Division::Builder(Multiplication::Builder(Rational(1),Symbol("x", 1)),Rational(2))); - assert_parsed_expression_is("(1)2", Multiplication::Builder(Parenthesis::Builder(Rational(1)),Rational(2))); - assert_parsed_expression_is("1(2)", Multiplication::Builder(Rational(1),Parenthesis::Builder(Rational(2)))); - assert_parsed_expression_is("sin(1)2", Multiplication::Builder(Sine::Builder(Rational(1)),Rational(2))); - assert_parsed_expression_is("1cos(2)", Multiplication::Builder(Rational(1),Cosine::Builder(Rational(2)))); - assert_parsed_expression_is("1!2", Multiplication::Builder(Factorial::Builder(Rational(1)),Rational(2))); - assert_parsed_expression_is("2X^(3)", Multiplication::Builder(Rational(2),Power::Builder(Constant(Ion::Charset::Exponential),Parenthesis::Builder(Rational(3))))); - Expression m1[] = {Rational(1)}; Matrix M1 = BuildMatrix(1,1,m1); - Expression m2[] = {Rational(2)}; Matrix M2 = BuildMatrix(1,1,m2); + assert_parsed_expression_is("1x", Multiplication::Builder(Rational::Builder(1),Symbol::Builder("x", 1))); + assert_parsed_expression_is("1ans", Multiplication::Builder(Rational::Builder(1),Symbol::Builder("ans", 3))); + assert_parsed_expression_is("x1", Symbol::Builder("x1", 2)); + assert_parsed_expression_is("1x+2", Addition::Builder(Multiplication::Builder(Rational::Builder(1),Symbol::Builder("x", 1)),Rational::Builder(2))); + assert_parsed_expression_is("1P", Multiplication::Builder(Rational::Builder(1),Constant::Builder(Ion::Charset::SmallPi))); + assert_parsed_expression_is("1x-2", Subtraction::Builder(Multiplication::Builder(Rational::Builder(1),Symbol::Builder("x", 1)),Rational::Builder(2))); + assert_parsed_expression_is("-1x", Opposite::Builder(Multiplication::Builder(Rational::Builder(1),Symbol::Builder("x", 1)))); + assert_parsed_expression_is("2*1x", Multiplication::Builder(Rational::Builder(2),Multiplication::Builder(Rational::Builder(1),Symbol::Builder("x", 1)))); + assert_parsed_expression_is("2^1x", Multiplication::Builder(Power::Builder(Rational::Builder(2),Rational::Builder(1)),Symbol::Builder("x", 1))); + assert_parsed_expression_is("1x^2", Multiplication::Builder(Rational::Builder(1),Power::Builder(Symbol::Builder("x", 1),Rational::Builder(2)))); + assert_parsed_expression_is("2/1x", Division::Builder(Rational::Builder(2),Multiplication::Builder(Rational::Builder(1),Symbol::Builder("x", 1)))); + assert_parsed_expression_is("1x/2", Division::Builder(Multiplication::Builder(Rational::Builder(1),Symbol::Builder("x", 1)),Rational::Builder(2))); + assert_parsed_expression_is("(1)2", Multiplication::Builder(Parenthesis::Builder(Rational::Builder(1)),Rational::Builder(2))); + assert_parsed_expression_is("1(2)", Multiplication::Builder(Rational::Builder(1),Parenthesis::Builder(Rational::Builder(2)))); + assert_parsed_expression_is("sin(1)2", Multiplication::Builder(Sine::Builder(Rational::Builder(1)),Rational::Builder(2))); + assert_parsed_expression_is("1cos(2)", Multiplication::Builder(Rational::Builder(1),Cosine::Builder(Rational::Builder(2)))); + assert_parsed_expression_is("1!2", Multiplication::Builder(Factorial::Builder(Rational::Builder(1)),Rational::Builder(2))); + assert_parsed_expression_is("2X^(3)", Multiplication::Builder(Rational::Builder(2),Power::Builder(Constant::Builder(Ion::Charset::Exponential),Parenthesis::Builder(Rational::Builder(3))))); + Expression m1[] = {Rational::Builder(1)}; Matrix M1 = BuildMatrix(1,1,m1); + Expression m2[] = {Rational::Builder(2)}; Matrix M2 = BuildMatrix(1,1,m2); assert_parsed_expression_is("[[1]][[2]]", Multiplication::Builder(M1,M2)); } diff --git a/poincare/test/properties.cpp b/poincare/test/properties.cpp index 685aea2b1..e36b93fb2 100644 --- a/poincare/test/properties.cpp +++ b/poincare/test/properties.cpp @@ -76,19 +76,19 @@ void assert_expression_has_characteristic_range(Expression e, float range, Prefe } QUIZ_CASE(poincare_characteristic_range) { - assert_expression_has_characteristic_range(Cosine::Builder(Symbol(Poincare::Symbol::SpecialSymbols::UnknownX)), 360.0f); - assert_expression_has_characteristic_range(Cosine::Builder(Opposite::Builder(Symbol(Poincare::Symbol::SpecialSymbols::UnknownX))), 360.0f); - assert_expression_has_characteristic_range(Cosine::Builder(Symbol(Poincare::Symbol::SpecialSymbols::UnknownX)), 2.0f*M_PI, Preferences::AngleUnit::Radian); - assert_expression_has_characteristic_range(Cosine::Builder(Opposite::Builder(Symbol(Poincare::Symbol::SpecialSymbols::UnknownX))), 2.0f*M_PI, Preferences::AngleUnit::Radian); - assert_expression_has_characteristic_range(Sine::Builder(Addition::Builder(Multiplication::Builder(Rational(9),Symbol(Poincare::Symbol::SpecialSymbols::UnknownX)),Rational(10))), 40.0f); - assert_expression_has_characteristic_range(Addition::Builder(Sine::Builder(Addition::Builder(Multiplication::Builder(Rational(9),Symbol(Poincare::Symbol::SpecialSymbols::UnknownX)),Rational(10))),Cosine::Builder(Division::Builder(Symbol(Poincare::Symbol::SpecialSymbols::UnknownX),Rational(2)))), 720.0f); - assert_expression_has_characteristic_range(Addition::Builder(Sine::Builder(Addition::Builder(Multiplication::Builder(Rational(9),Symbol(Poincare::Symbol::SpecialSymbols::UnknownX)),Rational(10))),Cosine::Builder(Division::Builder(Symbol(Poincare::Symbol::SpecialSymbols::UnknownX),Rational(2)))), 4.0f*M_PI, Preferences::AngleUnit::Radian); - assert_expression_has_characteristic_range(Symbol(Poincare::Symbol::SpecialSymbols::UnknownX), NAN); - assert_expression_has_characteristic_range(Addition::Builder(Cosine::Builder(Rational(3)),Rational(2)), 0.0f); - assert_expression_has_characteristic_range(CommonLogarithm::Builder(Cosine::Builder(Multiplication::Builder(Rational(40),Symbol(Poincare::Symbol::SpecialSymbols::UnknownX)))), 9.0f); - assert_expression_has_characteristic_range(Cosine::Builder((Expression)Cosine::Builder(Symbol(Poincare::Symbol::SpecialSymbols::UnknownX))), 360.0f); + assert_expression_has_characteristic_range(Cosine::Builder(Symbol::Builder(Poincare::Symbol::SpecialSymbols::UnknownX)), 360.0f); + assert_expression_has_characteristic_range(Cosine::Builder(Opposite::Builder(Symbol::Builder(Poincare::Symbol::SpecialSymbols::UnknownX))), 360.0f); + assert_expression_has_characteristic_range(Cosine::Builder(Symbol::Builder(Poincare::Symbol::SpecialSymbols::UnknownX)), 2.0f*M_PI, Preferences::AngleUnit::Radian); + assert_expression_has_characteristic_range(Cosine::Builder(Opposite::Builder(Symbol::Builder(Poincare::Symbol::SpecialSymbols::UnknownX))), 2.0f*M_PI, Preferences::AngleUnit::Radian); + assert_expression_has_characteristic_range(Sine::Builder(Addition::Builder(Multiplication::Builder(Rational::Builder(9),Symbol::Builder(Poincare::Symbol::SpecialSymbols::UnknownX)),Rational::Builder(10))), 40.0f); + assert_expression_has_characteristic_range(Addition::Builder(Sine::Builder(Addition::Builder(Multiplication::Builder(Rational::Builder(9),Symbol::Builder(Poincare::Symbol::SpecialSymbols::UnknownX)),Rational::Builder(10))),Cosine::Builder(Division::Builder(Symbol::Builder(Poincare::Symbol::SpecialSymbols::UnknownX),Rational::Builder(2)))), 720.0f); + assert_expression_has_characteristic_range(Addition::Builder(Sine::Builder(Addition::Builder(Multiplication::Builder(Rational::Builder(9),Symbol::Builder(Poincare::Symbol::SpecialSymbols::UnknownX)),Rational::Builder(10))),Cosine::Builder(Division::Builder(Symbol::Builder(Poincare::Symbol::SpecialSymbols::UnknownX),Rational::Builder(2)))), 4.0f*M_PI, Preferences::AngleUnit::Radian); + assert_expression_has_characteristic_range(Symbol::Builder(Poincare::Symbol::SpecialSymbols::UnknownX), NAN); + assert_expression_has_characteristic_range(Addition::Builder(Cosine::Builder(Rational::Builder(3)),Rational::Builder(2)), 0.0f); + assert_expression_has_characteristic_range(CommonLogarithm::Builder(Cosine::Builder(Multiplication::Builder(Rational::Builder(40),Symbol::Builder(Poincare::Symbol::SpecialSymbols::UnknownX)))), 9.0f); + assert_expression_has_characteristic_range(Cosine::Builder((Expression)Cosine::Builder(Symbol::Builder(Poincare::Symbol::SpecialSymbols::UnknownX))), 360.0f); assert_simplify("cos(x)>f(x)"); - assert_expression_has_characteristic_range(Function("f",1,Symbol(Poincare::Symbol::SpecialSymbols::UnknownX)), 360.0f); + assert_expression_has_characteristic_range(Function::Builder("f",1,Symbol::Builder(Poincare::Symbol::SpecialSymbols::UnknownX)), 360.0f); } void assert_parsed_expression_has_variables(const char * expression, const char * variables[], int trueNumberOfVariables) { diff --git a/poincare/test/rational.cpp b/poincare/test/rational.cpp index 4b090db03..66d42daaf 100644 --- a/poincare/test/rational.cpp +++ b/poincare/test/rational.cpp @@ -9,13 +9,13 @@ using namespace Poincare; QUIZ_CASE(poincare_rational_constructor) { int initialPoolSize = pool_size(); - Rational a("123","324"); - Rational b("3456"); - Rational c(123,324); - Rational d(3456789); + Rational a = Rational::Builder("123","324"); + Rational b = Rational::Builder("3456"); + Rational c = Rational::Builder(123,324); + Rational d = Rational::Builder(3456789); Integer overflow = Integer::Overflow(false); - Rational e(overflow); - Rational f(overflow, overflow); + Rational e = Rational::Builder(overflow); + Rational f = Rational::Builder(overflow, overflow); assert_pool_size(initialPoolSize+6); } @@ -35,31 +35,31 @@ static inline void assert_greater(const Rational i, const Rational j) { } QUIZ_CASE(poincare_rational_compare) { - assert_equal(Rational(123,324), Rational(41,108)); - assert_not_equal(Rational(123,234), Rational(42, 108)); - assert_lower(Rational(123,234), Rational(456,567)); - assert_lower(Rational(-123, 234),Rational(456, 567)); - assert_greater(Rational(123, 234),Rational(-456, 567)); - assert_greater(Rational(123, 234),Rational("123456789123456789", "12345678912345678910")); + assert_equal(Rational::Builder(123,324), Rational::Builder(41,108)); + assert_not_equal(Rational::Builder(123,234), Rational::Builder(42, 108)); + assert_lower(Rational::Builder(123,234), Rational::Builder(456,567)); + assert_lower(Rational::Builder(-123, 234),Rational::Builder(456, 567)); + assert_greater(Rational::Builder(123, 234),Rational::Builder(-456, 567)); + assert_greater(Rational::Builder(123, 234),Rational::Builder("123456789123456789", "12345678912345678910")); } QUIZ_CASE(poincare_rational_properties) { - quiz_assert(Rational(-2).sign() == ExpressionNode::Sign::Negative); - quiz_assert(Rational(-2, 3).sign() == ExpressionNode::Sign::Negative); - quiz_assert(Rational(2, 3).sign() == ExpressionNode::Sign::Positive); - quiz_assert(Rational(0, 3).sign() == ExpressionNode::Sign::Positive); - quiz_assert(Rational(0).isZero()); - quiz_assert(!Rational(231).isZero()); - quiz_assert(Rational(1).isOne()); - quiz_assert(!Rational(-1).isOne()); - quiz_assert(!Rational(1).isMinusOne()); - quiz_assert(Rational(-1).isMinusOne()); - quiz_assert(Rational(1,2).isHalf()); - quiz_assert(!Rational(-1).isHalf()); - quiz_assert(Rational(-1,2).isMinusHalf()); - quiz_assert(!Rational(3,2).isMinusHalf()); - quiz_assert(Rational(10).isTen()); - quiz_assert(!Rational(-1).isTen()); + quiz_assert(Rational::Builder(-2).sign() == ExpressionNode::Sign::Negative); + quiz_assert(Rational::Builder(-2, 3).sign() == ExpressionNode::Sign::Negative); + quiz_assert(Rational::Builder(2, 3).sign() == ExpressionNode::Sign::Positive); + quiz_assert(Rational::Builder(0, 3).sign() == ExpressionNode::Sign::Positive); + quiz_assert(Rational::Builder(0).isZero()); + quiz_assert(!Rational::Builder(231).isZero()); + quiz_assert(Rational::Builder(1).isOne()); + quiz_assert(!Rational::Builder(-1).isOne()); + quiz_assert(!Rational::Builder(1).isMinusOne()); + quiz_assert(Rational::Builder(-1).isMinusOne()); + quiz_assert(Rational::Builder(1,2).isHalf()); + quiz_assert(!Rational::Builder(-1).isHalf()); + quiz_assert(Rational::Builder(-1,2).isMinusHalf()); + quiz_assert(!Rational::Builder(3,2).isMinusHalf()); + quiz_assert(Rational::Builder(10).isTen()); + quiz_assert(!Rational::Builder(-1).isTen()); } static inline void assert_add_to(const Rational i, const Rational j, const Rational k) { @@ -67,9 +67,9 @@ static inline void assert_add_to(const Rational i, const Rational j, const Ratio } QUIZ_CASE(poincare_rational_addition) { - assert_add_to(Rational(1,2), Rational(1), Rational(3,2)); - assert_add_to(Rational("18446744073709551616","4294967296"), Rational(8,9), Rational("38654705672","9")); - assert_add_to(Rational("18446744073709551616","4294967296"), Rational(-8,9), Rational("38654705656","9")); + assert_add_to(Rational::Builder(1,2), Rational::Builder(1), Rational::Builder(3,2)); + assert_add_to(Rational::Builder("18446744073709551616","4294967296"), Rational::Builder(8,9), Rational::Builder("38654705672","9")); + assert_add_to(Rational::Builder("18446744073709551616","4294967296"), Rational::Builder(-8,9), Rational::Builder("38654705656","9")); } static inline void assert_pow_to(const Rational i,const Integer j, const Rational k) { @@ -77,8 +77,8 @@ static inline void assert_pow_to(const Rational i,const Integer j, const Rationa } QUIZ_CASE(poincare_rational_power) { - assert_pow_to(Rational(4,5), Rational(3).signedIntegerNumerator(), Rational(64,125)); - assert_pow_to(Rational(4,5), Rational(-3).signedIntegerNumerator(), Rational(125,64)); + assert_pow_to(Rational::Builder(4,5), Rational::Builder(3).signedIntegerNumerator(), Rational::Builder(64,125)); + assert_pow_to(Rational::Builder(4,5), Rational::Builder(-3).signedIntegerNumerator(), Rational::Builder(125,64)); } // Simplify @@ -137,12 +137,12 @@ QUIZ_CASE(poincare_rational_approximate) { //Serialize QUIZ_CASE(poincare_rational_serialize) { - assert_parsed_expression_serialize_to(Rational(-2, 3), "-2/3"); - assert_parsed_expression_serialize_to(Rational("2345678909876"), "2345678909876"); - assert_parsed_expression_serialize_to(Rational("-2345678909876", "5"), "-2345678909876/5"); - assert_parsed_expression_serialize_to(Rational(MaxIntegerString()), MaxIntegerString()); + assert_parsed_expression_serialize_to(Rational::Builder(-2, 3), "-2/3"); + assert_parsed_expression_serialize_to(Rational::Builder("2345678909876"), "2345678909876"); + assert_parsed_expression_serialize_to(Rational::Builder("-2345678909876", "5"), "-2345678909876/5"); + assert_parsed_expression_serialize_to(Rational::Builder(MaxIntegerString()), MaxIntegerString()); Integer one(1); Integer overflow = Integer::Overflow(false); - assert_parsed_expression_serialize_to(Rational(one, overflow), "1/inf"); - assert_parsed_expression_serialize_to(Rational(overflow), Infinity::Name()); + assert_parsed_expression_serialize_to(Rational::Builder(one, overflow), "1/inf"); + assert_parsed_expression_serialize_to(Rational::Builder(overflow), Infinity::Name()); } diff --git a/poincare/test/tree/blob_node.h b/poincare/test/tree/blob_node.h index 598fbbdb7..e2a0c907d 100644 --- a/poincare/test/tree/blob_node.h +++ b/poincare/test/tree/blob_node.h @@ -8,9 +8,9 @@ namespace Poincare { class BlobNode : public TreeNode { public: + BlobNode(int data) : m_data(data) {} virtual size_t size() const override { return sizeof(BlobNode); } int data() { return m_data; } - void setData(int data) { m_data = data; } virtual int numberOfChildren() const override { return 0; } #if POINCARE_TREE_LOG virtual void logNodeName(std::ostream & stream) const override { @@ -23,9 +23,13 @@ private: class BlobByReference : public TreeHandle { public: - BlobByReference(int data = 0) : TreeHandle(TreePool::sharedPool()->createTreeNode()) { - node()->setData(data); + static BlobByReference Builder(int data = 0) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(BlobNode)); + BlobNode * node = new (bufferNode) BlobNode(data); + TreeHandle h = TreeHandle::BuildWithBasicChildren(node); + return static_cast(h); } + BlobByReference() = delete; int data() { return node()->data(); } private: BlobNode * node() const { return static_cast(TreeHandle::node()); } diff --git a/poincare/test/tree/pair_node.h b/poincare/test/tree/pair_node.h index 2618aa0b0..c041e186b 100644 --- a/poincare/test/tree/pair_node.h +++ b/poincare/test/tree/pair_node.h @@ -3,6 +3,7 @@ #include #include +#include namespace Poincare { @@ -19,10 +20,14 @@ public: class PairByReference : public TreeHandle { public: - PairByReference(TreeHandle t1, TreeHandle t2) : TreeHandle(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, t1); - replaceChildAtIndexInPlace(1, t2); + static PairByReference Builder(TreeHandle t1, TreeHandle t2) { + void * bufferNode = TreePool::sharedPool()->alloc(sizeof(PairNode)); + PairNode * node = new (bufferNode) PairNode(); + TreeHandle children[2] = {t1, t2}; + TreeHandle h = TreeHandle::BuildWithBasicChildren(node, children, 2); + return static_cast(h); } + PairByReference() = delete; }; } diff --git a/poincare/test/tree/tree_handle.cpp b/poincare/test/tree/tree_handle.cpp index 44c380ca0..ff66ba727 100644 --- a/poincare/test/tree/tree_handle.cpp +++ b/poincare/test/tree/tree_handle.cpp @@ -13,14 +13,14 @@ using namespace Poincare; QUIZ_CASE(tree_handle_are_discared_after_block) { int initialPoolSize = pool_size(); { - BlobByReference b(0); + BlobByReference b = BlobByReference::Builder(0); assert_pool_size(initialPoolSize+1); } assert_pool_size(initialPoolSize); } static void make_temp_blob() { - BlobByReference b(5); + BlobByReference b = BlobByReference::Builder(5); } QUIZ_CASE(tree_handle_are_discared_after_function_call) { int initialPoolSize = pool_size(); @@ -31,7 +31,7 @@ QUIZ_CASE(tree_handle_are_discared_after_function_call) { QUIZ_CASE(tree_handle_can_be_copied) { int initialPoolSize = pool_size(); { - BlobByReference b(123); + BlobByReference b = BlobByReference::Builder(123); assert_pool_size(initialPoolSize+1); TreeHandle t = b; assert_pool_size(initialPoolSize+1); @@ -42,19 +42,19 @@ QUIZ_CASE(tree_handle_can_be_copied) { QUIZ_CASE(tree_handle_can_be_moved) { int initialPoolSize = pool_size(); { - TreeHandle t = BlobByReference(123); + TreeHandle t = BlobByReference::Builder(123); assert_pool_size(initialPoolSize+1); } { - TreeHandle t = BlobByReference(123); - t = BlobByReference(456); + TreeHandle t = BlobByReference::Builder(123); + t = BlobByReference::Builder(456); assert_pool_size(initialPoolSize+1); } assert_pool_size(initialPoolSize); } static TreeHandle blob_with_data_3() { - return BlobByReference(3); + return BlobByReference::Builder(3); } QUIZ_CASE(tree_handle_can_be_returned) { @@ -68,9 +68,9 @@ QUIZ_CASE(tree_handle_memory_failure) { int memoryFailureHasBeenHandled = false; Poincare::ExceptionCheckpoint ecp; if (ExceptionRun(ecp)) { - TreeHandle tree = BlobByReference(1); + TreeHandle tree = BlobByReference::Builder(1); while (true) { - tree = PairByReference(tree, BlobByReference(1)); + tree = PairByReference::Builder(tree, BlobByReference::Builder(1)); } } else { Poincare::Tidy(); @@ -82,10 +82,10 @@ QUIZ_CASE(tree_handle_memory_failure) { QUIZ_CASE(tree_handle_does_not_copy) { int initialPoolSize = pool_size(); - BlobByReference b1(1); - BlobByReference b2(2); + BlobByReference b1 = BlobByReference::Builder(1); + BlobByReference b2 = BlobByReference::Builder(2); assert_pool_size(initialPoolSize+2); - PairByReference p(b1, b2); + PairByReference p = PairByReference::Builder(b1, b2); assert_pool_size(initialPoolSize+3); PairByReference p2 = p; assert_pool_size(initialPoolSize+3); diff --git a/poincare/test/user_variable.cpp b/poincare/test/user_variable.cpp index eb4290428..8e336d245 100644 --- a/poincare/test/user_variable.cpp +++ b/poincare/test/user_variable.cpp @@ -157,9 +157,9 @@ QUIZ_CASE(poincare_user_variable_functions_with_context) { assert_simplify("x^2>f(x)"); // Approximate f(?-2) with ? = 5 const char x[] = {Symbol::SpecialSymbols::UnknownX, 0}; - assert_parsed_expression_approximates_with_value_for_symbol(Function("f", 1, Subtraction::Builder(Symbol(Symbol::SpecialSymbols::UnknownX), Rational(2))), x, 5.0, 9.0); + assert_parsed_expression_approximates_with_value_for_symbol(Function::Builder("f", 1, Subtraction::Builder(Symbol::Builder(Symbol::SpecialSymbols::UnknownX), Rational::Builder(2))), x, 5.0, 9.0); // Approximate f(?-1)+f(?+1) with ? = 3 - assert_parsed_expression_approximates_with_value_for_symbol(Addition::Builder(Function("f", 1, Subtraction::Builder(Symbol(Symbol::SpecialSymbols::UnknownX), Rational(1))), Function("f", 1, Addition::Builder(Symbol(Symbol::SpecialSymbols::UnknownX), Rational(1)))), x, 3.0, 20.0); + assert_parsed_expression_approximates_with_value_for_symbol(Addition::Builder(Function::Builder("f", 1, Subtraction::Builder(Symbol::Builder(Symbol::SpecialSymbols::UnknownX), Rational::Builder(1))), Function::Builder("f", 1, Addition::Builder(Symbol::Builder(Symbol::SpecialSymbols::UnknownX), Rational::Builder(1)))), x, 3.0, 20.0); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); @@ -168,9 +168,9 @@ QUIZ_CASE(poincare_user_variable_functions_with_context) { assert_simplify("R(-1)*R(-1)>f(x)"); // Approximate f(?) with ? = 5 // Cartesian - assert_parsed_expression_approximates_with_value_for_symbol(Function("f", 1, Symbol(Symbol::SpecialSymbols::UnknownX)), x, 1.0, -1.0); + assert_parsed_expression_approximates_with_value_for_symbol(Function::Builder("f", 1, Symbol::Builder(Symbol::SpecialSymbols::UnknownX)), x, 1.0, -1.0); // Real - assert_parsed_expression_approximates_with_value_for_symbol(Function("f", 1, Symbol(Symbol::SpecialSymbols::UnknownX)), x, 1.0, (double)NAN, Real); + assert_parsed_expression_approximates_with_value_for_symbol(Function::Builder("f", 1, Symbol::Builder(Symbol::SpecialSymbols::UnknownX)), x, 1.0, (double)NAN, Real); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); @@ -180,15 +180,15 @@ QUIZ_CASE(poincare_user_variable_properties) { Shared::GlobalContext context; assert_parsed_expression_evaluates_to("[[1]]>a", "[[1]]"); - quiz_assert(Symbol('a').isApproximate(context)); - quiz_assert(Poincare::Expression::IsMatrix(Symbol('a'), context, true)); + quiz_assert(Symbol::Builder('a').isApproximate(context)); + quiz_assert(Poincare::Expression::IsMatrix(Symbol::Builder('a'), context, true)); /* [[x]]->f(x) expression contains a matrix, so its simplification is going * to be interrupted. We thus rather approximate it instead of simplifying it. * TODO: use parse_and_simplify when matrix are simplified. */ assert_parsed_expression_evaluates_to("[[x]]>f(x)", "[[undef]]"); - quiz_assert(Function("f", 1, Rational(2)).isApproximate(context)); - quiz_assert(Poincare::Expression::IsMatrix(Function("f", 1, Symbol('x')), context, true)); + quiz_assert(Function::Builder("f", 1, Rational::Builder(2)).isApproximate(context)); + quiz_assert(Poincare::Expression::IsMatrix(Function::Builder("f", 1, Symbol::Builder('x')), context, true)); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); diff --git a/poincare/test/vertical_offset_layout.cpp b/poincare/test/vertical_offset_layout.cpp index 7379abfa7..4c4e71750 100644 --- a/poincare/test/vertical_offset_layout.cpp +++ b/poincare/test/vertical_offset_layout.cpp @@ -8,7 +8,7 @@ using namespace Poincare; QUIZ_CASE(poincare_vertical_offset_layout_serialize) { HorizontalLayout layout = HorizontalLayout::Builder( - CharLayout('2'), + CharLayout::Builder('2'), VerticalOffsetLayout::Builder( LayoutHelper::String("x+5", 3), VerticalOffsetLayoutNode::Type::Superscript