diff --git a/.github/workflows/ci-workflow.yml b/.github/workflows/ci-workflow.yml index a67660ad2..128cdffcc 100644 --- a/.github/workflows/ci-workflow.yml +++ b/.github/workflows/ci-workflow.yml @@ -77,4 +77,4 @@ jobs: with: name: epsilon-linux.bin path: output/release/simulator/linux/epsilon.bin - - run: make -j2 PLATFORM=simulator test.headless.bin \ No newline at end of file + - run: make -j2 PLATFORM=simulator test.headless.bin diff --git a/apps/Makefile b/apps/Makefile index 0d3fec7cf..84268fdbb 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -57,6 +57,9 @@ $(call object_for,apps/apps_container_storage.cpp apps/apps_container.cpp apps/m SFLAGS += -I$(BUILD_DIR) i18n_files += $(addprefix apps/language_,$(addsuffix .universal.i18n, $(EPSILON_I18N))) +ifeq ($(EPSILON_GETOPT),1) +i18n_files += $(addprefix apps/language_,$(addsuffix _iso6391.universal.i18n, $(EPSILON_I18N))) +endif i18n_files += $(addprefix apps/,\ shared.de.i18n\ shared.en.i18n\ @@ -83,7 +86,7 @@ $(eval $(call rule_for, \ I18N, \ apps/i18n.cpp, \ $(i18n_files), \ - $$(PYTHON) apps/i18n.py --codepoints $(code_points) --header $$(subst .cpp,.h,$$@) --implementation $$@ --locales $$(EPSILON_I18N) --files $$^, \ + $$(PYTHON) apps/i18n.py --codepoints $(code_points) --header $$(subst .cpp,.h,$$@) --implementation $$@ --locales $$(EPSILON_I18N) --files $$^ --generateISO6391locales $$(EPSILON_GETOPT), \ global \ )) diff --git a/apps/apps_container.h b/apps/apps_container.h index 814e642a1..99d219ee9 100644 --- a/apps/apps_container.h +++ b/apps/apps_container.h @@ -36,7 +36,7 @@ public: MathToolbox * mathToolbox(); VariableBoxController * variableBoxController(); void suspend(bool checkIfOnOffKeyReleased = false); - virtual bool dispatchEvent(Ion::Events::Event event) override; + bool dispatchEvent(Ion::Events::Event event) override; bool switchTo(App::Snapshot * snapshot) override; void run() override; bool updateBatteryState(); diff --git a/apps/calculation/additional_outputs/complex_graph_cell.cpp b/apps/calculation/additional_outputs/complex_graph_cell.cpp index 46dee7f6d..bc8a687b3 100644 --- a/apps/calculation/additional_outputs/complex_graph_cell.cpp +++ b/apps/calculation/additional_outputs/complex_graph_cell.cpp @@ -39,7 +39,7 @@ void ComplexGraphView::drawRect(KDContext * ctx, KDRect rect) const { * and the line of equation (real*t,imag*t). * (a*cos(t), b*sin(t)) = (real*t,imag*t) --> tan(t) = sign(a)*sign(b) (± π) * --> t = π/4 [π/2] according to sign(a) and sign(b). */ - float th = real < 0.0f ? 3.0f*M_PI/4.0f : M_PI/4.0f; + float th = real < 0.0f ? (float)(3.0*M_PI_4) : (float)M_PI_4; th = imag < 0.0f ? -th : th; // Compute ellipsis parameters a and b float factor = 5.0f; @@ -48,7 +48,7 @@ void ComplexGraphView::drawRect(KDContext * ctx, KDRect rect) const { // Avoid flat ellipsis for edge cases (for real = 0, the case imag = 0 is excluded) if (real == 0.0f) { a = 1.0f/factor; - th = imag < 0.0f ? -M_PI/2.0f : M_PI/2.0f; + th = imag < 0.0f ? (float)-M_PI_2 : (float)M_PI_2; } std::complex parameters(a,b); drawCurve(ctx, rect, 0.0f, 1.0f, 0.01f, diff --git a/apps/calculation/additional_outputs/expressions_list_controller.h b/apps/calculation/additional_outputs/expressions_list_controller.h index afc59e9c1..df8f8e4ff 100644 --- a/apps/calculation/additional_outputs/expressions_list_controller.h +++ b/apps/calculation/additional_outputs/expressions_list_controller.h @@ -28,7 +28,7 @@ public: protected: constexpr static int k_maxNumberOfCells = 4; - virtual int textAtIndex(char * buffer, size_t bufferSize, int index) override; + int textAtIndex(char * buffer, size_t bufferSize, int index) override; Poincare::Expression m_expression; // Memoization of layouts mutable Poincare::Layout m_layouts[k_maxNumberOfCells]; diff --git a/apps/calculation/additional_outputs/trigonometry_model.h b/apps/calculation/additional_outputs/trigonometry_model.h index cf31fb1f8..c299565a8 100644 --- a/apps/calculation/additional_outputs/trigonometry_model.h +++ b/apps/calculation/additional_outputs/trigonometry_model.h @@ -18,7 +18,7 @@ public: float yMax() const override { return yCenter() + yHalfRange(); } void setAngle(float f) { m_angle = f; } - float angle() const { return m_angle*M_PI/Poincare::Trigonometry::PiInAngleUnit(Poincare::Preferences::sharedPreferences()->angleUnit()); } + float angle() const { return m_angle*(float)M_PI/(float)Poincare::Trigonometry::PiInAngleUnit(Poincare::Preferences::sharedPreferences()->angleUnit()); } private: constexpr static float k_xHalfRange = 2.1f; // We center the yRange around the semi-circle where the angle is diff --git a/apps/calculation/calculation.cpp b/apps/calculation/calculation.cpp index 90f2de0f0..0ed9a2a85 100644 --- a/apps/calculation/calculation.cpp +++ b/apps/calculation/calculation.cpp @@ -7,14 +7,13 @@ #include #include #include +#include using namespace Poincare; using namespace Shared; namespace Calculation { -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } - bool Calculation::operator==(const Calculation& c) { return strcmp(inputText(), c.inputText()) == 0 && strcmp(approximateOutputText(NumberOfSignificantDigits::Maximal), c.approximateOutputText(NumberOfSignificantDigits::Maximal)) == 0 @@ -164,7 +163,7 @@ KDCoordinate Calculation::height(Context * context, bool expanded, bool allExpre singleLine = exactOutputWidth + inputWidth < maxWidth - 40; if (singleLine && Poincare::Preferences::sharedPreferences()->resultDisplay() == Poincare::Preferences::ResultDisplay::Compact && !allExpressionsInline) { KDCoordinate exactOutputBaseline = exactLayout.baseline(); - result = maxCoordinate(inputBaseline, exactOutputBaseline) + maxCoordinate(inputHeight - inputBaseline, exactOutputHeight-exactOutputBaseline) + singleMargin; + result = std::max(inputBaseline, exactOutputBaseline) + std::max(inputHeight - inputBaseline, exactOutputHeight-exactOutputBaseline) + singleMargin; } else { if (allExpressionsInline) { KDCoordinate exactOutputBaseline = exactLayout.baseline(); @@ -198,11 +197,11 @@ KDCoordinate Calculation::height(Context * context, bool expanded, bool allExpre if (displayOutput(context) == DisplayOutput::ApproximateOnly || (!expanded && displayOutput(context) == DisplayOutput::ExactAndApproximateToggle)) { if (singleLine && Poincare::Preferences::sharedPreferences()->resultDisplay() == Poincare::Preferences::ResultDisplay::Compact && !allExpressionsInline) { KDCoordinate approximateOutputBaseline = approximateLayout.baseline(); - result = maxCoordinate(inputBaseline, approximateOutputBaseline) + maxCoordinate(inputHeight - inputBaseline, approximateOutputHeight-approximateOutputBaseline) + singleMargin; + result = std::max(inputBaseline, approximateOutputBaseline) + std::max(inputHeight - inputBaseline, approximateOutputHeight-approximateOutputBaseline) + singleMargin; } else { if (allExpressionsInline) { KDCoordinate approximateOutputBaseline = approximateLayout.baseline(); - result = maxCoordinate(inputBaseline, approximateOutputBaseline) + maxCoordinate(inputHeight - inputBaseline, approximateOutputHeight-approximateOutputBaseline); + result = std::max(inputBaseline, approximateOutputBaseline) + std::max(inputHeight - inputBaseline, approximateOutputHeight-approximateOutputBaseline); } else { result = inputHeight + approximateOutputHeight + doubleMargin; } @@ -216,12 +215,12 @@ KDCoordinate Calculation::height(Context * context, bool expanded, bool allExpre singleLine = exactOutputWidth + approximateOutputWidth + inputWidth < maxWidth - 70; KDCoordinate approximateOutputBaseline = approximateLayout.baseline(); if (singleLine && Poincare::Preferences::sharedPreferences()->resultDisplay() == Poincare::Preferences::ResultDisplay::Compact) { - result = maxCoordinate(inputBaseline, maxCoordinate(exactOutputBaseline, approximateOutputBaseline)) + maxCoordinate(inputHeight - inputBaseline, maxCoordinate(exactOutputHeight - exactOutputBaseline, approximateOutputHeight-approximateOutputBaseline)) + singleMargin; + result = std::max(inputBaseline, std::max(exactOutputBaseline, approximateOutputBaseline)) + std::max(inputHeight - inputBaseline, std::max(exactOutputHeight - exactOutputBaseline, approximateOutputHeight-approximateOutputBaseline)) + singleMargin; } else { if (allExpressionsInline) { - result = maxCoordinate(inputBaseline, maxCoordinate(exactOutputBaseline, approximateOutputBaseline)) + maxCoordinate(inputHeight - inputBaseline, maxCoordinate(exactOutputHeight - exactOutputBaseline, approximateOutputHeight-approximateOutputBaseline)); + result = std::max(inputBaseline, std::max(exactOutputBaseline, approximateOutputBaseline)) + std::max(inputHeight - inputBaseline, std::max(exactOutputHeight - exactOutputBaseline, approximateOutputHeight-approximateOutputBaseline)); } else { - KDCoordinate outputHeight = maxCoordinate(exactOutputBaseline, approximateOutputBaseline) + maxCoordinate(exactOutputHeight-exactOutputBaseline, approximateOutputHeight-approximateOutputBaseline); + KDCoordinate outputHeight = std::max(exactOutputBaseline, approximateOutputBaseline) + std::max(exactOutputHeight-exactOutputBaseline, approximateOutputHeight-approximateOutputBaseline); result = inputHeight + outputHeight + doubleMargin; } } diff --git a/apps/calculation/history_view_cell.cpp b/apps/calculation/history_view_cell.cpp index 8a784bef2..74de1ce3d 100644 --- a/apps/calculation/history_view_cell.cpp +++ b/apps/calculation/history_view_cell.cpp @@ -5,12 +5,10 @@ #include #include #include +#include namespace Calculation { -static inline KDCoordinate minCoordinate(KDCoordinate x, KDCoordinate y) { return x < y ? x : y; } -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } - /* HistoryViewCellDataSource */ HistoryViewCellDataSource::HistoryViewCellDataSource() : @@ -182,16 +180,16 @@ void HistoryViewCell::layoutSubviews(bool force) { KDSize inputSize = m_inputView.minimalSizeForOptimalDisplay(); m_inputView.setFrame(KDRect( 0, 0, - minCoordinate(maxFrameWidth, inputSize.width()), + std::min(maxFrameWidth, inputSize.width()), inputSize.height()), force); KDSize outputSize = m_scrollableOutputView.minimalSizeForOptimalDisplay(); int singleLine = outputSize.width() + inputSize.width() < bounds().width() - 6; int outputHeight = (singleLine && Poincare::Preferences::sharedPreferences()->resultDisplay() == Poincare::Preferences::ResultDisplay::Compact) ? (maxCoordinate(0, inputSize.height() - outputSize.height()) / 2) + maxCoordinate(0, (inputSize.height() - outputSize.height()) / 2) : inputSize.height(); m_scrollableOutputView.setFrame(KDRect( - maxCoordinate(0, maxFrameWidth - outputSize.width()), + std::max(0, maxFrameWidth - outputSize.width()), outputHeight, - minCoordinate(maxFrameWidth, outputSize.width()), + std::min(maxFrameWidth, outputSize.width()), outputSize.height()), force); } diff --git a/apps/code/console_controller.cpp b/apps/code/console_controller.cpp index 1cdb14113..11dd7c076 100644 --- a/apps/code/console_controller.cpp +++ b/apps/code/console_controller.cpp @@ -3,6 +3,7 @@ #include "script.h" #include "variable_box_controller.h" #include +#include #include #include #include @@ -16,8 +17,6 @@ extern "C" { namespace Code { -static inline int minInt(int x, int y) { return x < y ? x : y; } - static const char * sStandardPromptText = ">>> "; ConsoleController::ConsoleController(Responder * parentResponder, App * pythonDelegate, ScriptStore * scriptStore @@ -488,7 +487,7 @@ void ConsoleController::autoImportScript(Script script, bool force) { /* Copy the script name without the extension ".py". The '.' is overwritten * by the null terminating char. */ - int copySizeWithNullTerminatingZero = minInt(k_maxImportCommandSize - currentChar, strlen(scriptName) - strlen(ScriptStore::k_scriptExtension)); + int copySizeWithNullTerminatingZero = std::min(k_maxImportCommandSize - currentChar, strlen(scriptName) - strlen(ScriptStore::k_scriptExtension)); assert(copySizeWithNullTerminatingZero >= 0); assert(copySizeWithNullTerminatingZero <= k_maxImportCommandSize - currentChar); strlcpy(command+currentChar, scriptName, copySizeWithNullTerminatingZero); diff --git a/apps/code/console_edit_cell.cpp b/apps/code/console_edit_cell.cpp index f938f52dc..f82d5d596 100644 --- a/apps/code/console_edit_cell.cpp +++ b/apps/code/console_edit_cell.cpp @@ -4,11 +4,10 @@ #include #include #include +#include namespace Code { -static inline int minInt(int x, int y) { return x < y ? x : y; } - ConsoleEditCell::ConsoleEditCell(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * delegate) : HighlightCell(), Responder(parentResponder), @@ -70,7 +69,7 @@ const char * ConsoleEditCell::shiftCurrentTextAndClear() { char * textFieldBuffer = const_cast(m_textField.text()); char * newTextPosition = textFieldBuffer + 1; assert(previousBufferSize > 0); - size_t copyLength = minInt(previousBufferSize - 1, strlen(textFieldBuffer)); + size_t copyLength = std::min(previousBufferSize - 1, strlen(textFieldBuffer)); memmove(newTextPosition, textFieldBuffer, copyLength); newTextPosition[copyLength] = 0; textFieldBuffer[0] = 0; diff --git a/apps/code/console_store.cpp b/apps/code/console_store.cpp index 390ba860e..e4ff3fa35 100644 --- a/apps/code/console_store.cpp +++ b/apps/code/console_store.cpp @@ -1,10 +1,9 @@ #include "console_store.h" #include +#include namespace Code { -static inline int minInt(int x, int y) { return x < y ? x : y; } - void ConsoleStore::startNewSession() { if (k_historySize < 1) { return; @@ -12,7 +11,7 @@ void ConsoleStore::startNewSession() { m_history[0] = makePrevious(m_history[0]); - for (int i = 0; i < k_historySize - 1; i++) { + for (size_t i = 0; i < k_historySize - 1; i++) { if (m_history[i] == 0) { if (m_history[i+1] == 0) { return ; @@ -25,7 +24,7 @@ void ConsoleStore::startNewSession() { ConsoleLine ConsoleStore::lineAtIndex(int i) const { assert(i >= 0 && i < numberOfLines()); int currentLineIndex = 0; - for (int j=0; j k_historySize - 1) { textLength = k_historySize - 1 - 1 - 1; // Marker, null termination and null marker. } - int i = indexOfNullMarker(); + size_t i = indexOfNullMarker(); // If needed, make room for the text we want to push. while (i + ConsoleLine::sizeOfConsoleLine(textLength) > k_historySize - 1) { deleteFirstLine(); i = indexOfNullMarker(); } m_history[i] = marker; - strlcpy(&m_history[i+1], text, minInt(k_historySize-(i+1),textLength+1)); + strlcpy(&m_history[i+1], text, std::min(k_historySize-(i+1),textLength+1)); m_history[i+1+textLength+1] = 0; return &m_history[i+1]; } @@ -113,11 +112,11 @@ ConsoleLine::Type ConsoleStore::lineTypeForMarker(char marker) const { return static_cast(marker-1); } -int ConsoleStore::indexOfNullMarker() const { +size_t ConsoleStore::indexOfNullMarker() const { if (m_history[0] == 0) { return 0; } - for (int i=0; i=0 && index < numberOfLines()); int currentLineIndex = 0; - for (int i = 0; i < k_historySize - 1; i++) { + for (size_t i = 0; i < k_historySize - 1; i++) { if (m_history[i] == 0) { currentLineIndex++; continue; } if (currentLineIndex == index) { - int nextLineStart = i; + size_t nextLineStart = i; while (m_history[nextLineStart] != 0 && nextLineStart < k_historySize - 2) { nextLineStart++; } @@ -158,7 +157,7 @@ void ConsoleStore::deleteFirstLine() { secondLineMarkerIndex++; } secondLineMarkerIndex++; - for (int i=0; i +#include namespace Code { @@ -21,8 +22,6 @@ constexpr KDColor StringColor = Palette::CodeString; constexpr KDColor BackgroundColor = Palette::CodeBackground; constexpr KDColor HighlightColor = Palette::CodeBackgroundSelected; -static inline const char * minPointer(const char * x, const char * y) { return x < y ? x : y; } - static inline KDColor TokenColor(mp_token_kind_t tokenKind) { if (tokenKind == MP_TOKEN_STRING) { return StringColor; @@ -84,7 +83,7 @@ void PythonTextArea::ContentView::drawLine(KDContext * ctx, int line, const char line, fromColumn, lineStart, - minPointer(text + byteLength, lineEnd) - lineStart, + std::min(text + byteLength, lineEnd) - lineStart, StringColor, BackgroundColor, selectionStart, @@ -107,7 +106,7 @@ void PythonTextArea::ContentView::drawLine(KDContext * ctx, int line, const char line, fromColumn, spacesStart, - minPointer(text + byteLength, firstNonSpace) - spacesStart, + std::min(text + byteLength, firstNonSpace) - spacesStart, StringColor, BackgroundColor, selectionStart, @@ -135,7 +134,7 @@ void PythonTextArea::ContentView::drawLine(KDContext * ctx, int line, const char line, UTF8Helper::GlyphOffsetAtCodePoint(text, tokenEnd), tokenEnd, - minPointer(text + byteLength, tokenFrom) - tokenEnd, + std::min(text + byteLength, tokenFrom) - tokenEnd, StringColor, BackgroundColor, selectionStart, diff --git a/apps/exam_pop_up_controller.h b/apps/exam_pop_up_controller.h index 3ef7285eb..c335126f7 100644 --- a/apps/exam_pop_up_controller.h +++ b/apps/exam_pop_up_controller.h @@ -8,7 +8,7 @@ class HighContrastButton : public Button { public: using Button::Button; - virtual KDColor highlightedBackgroundColor() const override { return Palette::ButtonBackgroundSelectedHighContrast; } + KDColor highlightedBackgroundColor() const override { return Palette::ButtonBackgroundSelectedHighContrast; } }; class ExamPopUpController : public ViewController { diff --git a/apps/graph/graph/graph_controller.cpp b/apps/graph/graph/graph_controller.cpp index 74cc400dc..cc9dbb93a 100644 --- a/apps/graph/graph/graph_controller.cpp +++ b/apps/graph/graph/graph_controller.cpp @@ -1,16 +1,12 @@ #include "graph_controller.h" #include "../app.h" +#include using namespace Poincare; using namespace Shared; namespace Graph { -static inline float minFloat(float x, float y) { return x < y ? x : y; } -static inline float maxFloat(float x, float y) { return x > y ? x : y; } -static inline double minDouble(double x, double y) { return x < y ? x : y; } -static inline double maxDouble(double x, double y) { return x > y ? x : y; } - GraphController::GraphController(Responder * parentResponder, ::InputEventHandlerDelegate * inputEventHandlerDelegate, Shared::InteractiveCurveViewRange * curveViewRange, CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * previousModelsVersions, uint32_t * rangeVersion, Poincare::Preferences::AngleUnit * angleUnitVersion, ButtonRowController * header) : FunctionGraphController(parentResponder, inputEventHandlerDelegate, header, curveViewRange, &m_view, cursor, indexFunctionSelectedByCursor, modelVersion, previousModelsVersions, rangeVersion, angleUnitVersion), m_bannerView(this, inputEventHandlerDelegate, this), @@ -52,10 +48,10 @@ void GraphController::interestingFunctionRange(ExpiringPointertMin())); assert(!std::isnan(f->tMax())); - const double tMin = maxFloat(f->tMin(), resultxMin); - const double tMax = minFloat(f->tMax(), resultxMax); + const double tMin = std::max(f->tMin(), resultxMin); + const double tMax = std::min(f->tMax(), resultxMax); const double step = (tMax - tMin) / (2.0 * (m_view.bounds().width() - 1.0)); interestingFunctionRange(f, tMin, tMax, step, &resultxMin, &resultxMax, &resultyMin, &resultyMax); } @@ -129,12 +125,12 @@ float GraphController::interestingXHalfRange() const { ExpiringPointer f = store->modelForRecord(store->activeRecordAtIndex(i)); float fRange = f->expressionReduced(context).characteristicXRange(context, Poincare::Preferences::sharedPreferences()->angleUnit()); if (!std::isnan(fRange) && !std::isinf(fRange)) { - characteristicRange = maxFloat(fRange, characteristicRange); + characteristicRange = std::max(fRange, characteristicRange); } // Compute the combined range of the functions assert(f->plotType() == ContinuousFunction::PlotType::Cartesian); // So that tMin tMax represents xMin xMax - tMin = minDouble(tMin, f->tMin()); - tMax = maxDouble(tMax, f->tMax()); + tMin = std::min(tMin, f->tMin()); + tMax = std::max(tMax, f->tMax()); } constexpr float rangeMultiplicator = 1.6f; if (characteristicRange > 0.0f ) { @@ -145,7 +141,7 @@ float GraphController::interestingXHalfRange() const { if (tMin >= -defaultXHalfRange && tMax <= defaultXHalfRange) { /* If the combined Range of the functions is smaller than the default range, * use it. */ - float f = rangeMultiplicator * (float)maxDouble(std::fabs(tMin), std::fabs(tMax)); + float f = rangeMultiplicator * (float)std::max(std::fabs(tMin), std::fabs(tMax)); return (std::isnan(f) || std::isinf(f)) ? defaultXHalfRange : f; } return defaultXHalfRange; @@ -226,7 +222,7 @@ void GraphController::jumpToLeftRightCurve(double t, int direction, int function if (currentXDelta <= xDelta) { double potentialNextTMin = f->tMin(); double potentialNextTMax = f->tMax(); - double potentialNextT = maxDouble(potentialNextTMin, minDouble(potentialNextTMax, t)); + double potentialNextT = std::max(potentialNextTMin, std::min(potentialNextTMax, t)); Coordinate2D xy = f->evaluateXYAtParameter(potentialNextT, App::app()->localContext()); if (currentXDelta < xDelta || std::abs(xy.x2() - m_cursor->y()) < std::abs(nextY - m_cursor->y())) { nextCurveIndex = i; diff --git a/apps/graph/graph/graph_controller_helper.cpp b/apps/graph/graph/graph_controller_helper.cpp index 0c21be79c..ad42ac727 100644 --- a/apps/graph/graph/graph_controller_helper.cpp +++ b/apps/graph/graph/graph_controller_helper.cpp @@ -3,15 +3,13 @@ #include "../app.h" #include "../../shared/poincare_helpers.h" #include +#include using namespace Shared; using namespace Poincare; namespace Graph { -static inline double minDouble(double x, double y) { return x < y ? x : y; } -static inline double maxDouble(double x, double y) { return x > y ? x : y; } - bool GraphControllerHelper::privateMoveCursorHorizontally(Shared::CurveViewCursor * cursor, int direction, Shared::InteractiveCurveViewRange * range, int numberOfStepsInGradUnit, Ion::Storage::Record record, bool fast) { ExpiringPointer function = App::app()->functionStore()->modelForRecord(record); double tCursorPosition = cursor->t(); @@ -34,7 +32,7 @@ bool GraphControllerHelper::privateMoveCursorHorizontally(Shared::CurveViewCurso step *= 5.0; } t += dir * step; - t = maxDouble(tMin, minDouble(tMax, t)); + t = std::max(tMin, std::min(tMax, t)); Coordinate2D xy = function->evaluateXYAtParameter(t, App::app()->localContext()); cursor->moveTo(t, xy.x1(), xy.x2()); return true; diff --git a/apps/graph/list/text_field_function_title_cell.cpp b/apps/graph/list/text_field_function_title_cell.cpp index a1d138e24..55c7f6676 100644 --- a/apps/graph/list/text_field_function_title_cell.cpp +++ b/apps/graph/list/text_field_function_title_cell.cpp @@ -1,12 +1,10 @@ #include "text_field_function_title_cell.h" #include "list_controller.h" #include +#include namespace Graph { -static inline float minFloat(float x, float y) { return x < y ? x : y; } -static inline float maxFloat(float x, float y) { return x > y ? x : y; } - TextFieldFunctionTitleCell::TextFieldFunctionTitleCell(ListController * listController, Orientation orientation, const KDFont * font) : Shared::FunctionTitleCell(orientation), Responder(listController), @@ -56,9 +54,9 @@ void TextFieldFunctionTitleCell::layoutSubviews(bool force) { KDRect frame = subviewFrame(); m_textField.setFrame(frame, force); KDCoordinate maxTextFieldX = frame.width() - m_textField.minimalSizeForOptimalDisplay().width(); - float horizontalAlignment = maxFloat( + float horizontalAlignment = std::max( 0.0f, - minFloat( + std::min( 1.0f, ((float)(maxTextFieldX - k_textFieldRightMargin))/((float)maxTextFieldX))); m_textField.setAlignment(horizontalAlignment, verticalAlignment()); diff --git a/apps/home/controller.h b/apps/home/controller.h index 428de3ccb..c49848480 100644 --- a/apps/home/controller.h +++ b/apps/home/controller.h @@ -17,12 +17,12 @@ public: void viewWillAppear() override; void viewDidDisappear() override; - virtual int numberOfRows() const override; - virtual int numberOfColumns() const override; - virtual KDCoordinate cellHeight() override; - virtual KDCoordinate cellWidth() override; - virtual HighlightCell * reusableCell(int index) override; - virtual int reusableCellCount() const override; + int numberOfRows() const override; + int numberOfColumns() const override; + KDCoordinate cellHeight() override; + KDCoordinate cellWidth() override; + HighlightCell * reusableCell(int index) override; + int reusableCellCount() const override; void willDisplayCellAtLocation(HighlightCell * cell, int i, int j) override; void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) override; private: diff --git a/apps/i18n.py b/apps/i18n.py index 6ed920a40..a6130e49a 100644 --- a/apps/i18n.py +++ b/apps/i18n.py @@ -19,9 +19,13 @@ parser.add_argument('--implementation', help='the .cpp file to generate') parser.add_argument('--locales', nargs='+', help='locale to actually generate') parser.add_argument('--codepoints', help='the code_points.h file') parser.add_argument('--files', nargs='+', help='an i18n file') +parser.add_argument('--generateISO6391locales', type=int, nargs='+', help='whether to generate the ISO6391 codes for the languages (for instance "en" for english)') args = parser.parse_args() +def generate_ISO6391(): + return args.generateISO6391locales[0] == 1 + def has_glyph(glyph): return glyph in codepoints @@ -143,6 +147,14 @@ def print_header(data, path, locales): for locale in locales: f.write(" Message::Language" + locale.upper() + ",\n") f.write("};\n\n") + + if generate_ISO6391(): + # Language ISO639-1 codes + f.write("constexpr const Message LanguageISO6391Names[NumberOfLanguages] = {\n"); + for locale in locales: + f.write(" Message::LanguageISO6391" + locale.upper() + ",\n") + f.write("};\n\n") + f.write("}\n\n") f.write("#endif\n") f.close() diff --git a/apps/language_de_iso6391.universal.i18n b/apps/language_de_iso6391.universal.i18n new file mode 100644 index 000000000..8d811650d --- /dev/null +++ b/apps/language_de_iso6391.universal.i18n @@ -0,0 +1 @@ +LanguageISO6391DE = "de" diff --git a/apps/language_en_iso6391.universal.i18n b/apps/language_en_iso6391.universal.i18n new file mode 100644 index 000000000..54972ae84 --- /dev/null +++ b/apps/language_en_iso6391.universal.i18n @@ -0,0 +1 @@ +LanguageISO6391EN = "en" diff --git a/apps/language_es_iso6391.universal.i18n b/apps/language_es_iso6391.universal.i18n new file mode 100644 index 000000000..615cbf978 --- /dev/null +++ b/apps/language_es_iso6391.universal.i18n @@ -0,0 +1 @@ +LanguageISO6391ES = "es" diff --git a/apps/language_fr_iso6391.universal.i18n b/apps/language_fr_iso6391.universal.i18n new file mode 100644 index 000000000..905e6f179 --- /dev/null +++ b/apps/language_fr_iso6391.universal.i18n @@ -0,0 +1 @@ +LanguageISO6391FR = "fr" diff --git a/apps/language_hu_iso6391.universal.i18n b/apps/language_hu_iso6391.universal.i18n new file mode 100644 index 000000000..98bc27af1 --- /dev/null +++ b/apps/language_hu_iso6391.universal.i18n @@ -0,0 +1 @@ +LanguageISO6391HU = "hu" diff --git a/apps/language_pt_iso6391.universal.i18n b/apps/language_pt_iso6391.universal.i18n new file mode 100644 index 000000000..15218e760 --- /dev/null +++ b/apps/language_pt_iso6391.universal.i18n @@ -0,0 +1 @@ +LanguageISO6391PT = "pt" diff --git a/apps/main.cpp b/apps/main.cpp index 8b5a13e61..d0dcf00b7 100644 --- a/apps/main.cpp +++ b/apps/main.cpp @@ -31,11 +31,13 @@ void ion_main(int argc, const char * const argv[]) { * $ ./epsilon.elf --language fr */ if (strcmp(argv[i], "--language") == 0 && argc > i+1) { - const char * languageIdentifiers[] = {"none", "en", "fr", "es", "de", "pt"}; const char * requestedLanguageId = argv[i+1]; - for (int i=0; isetLanguage((I18n::Language)i); + if (strcmp(requestedLanguageId, "none") == 0) { + continue; + } + for (int j = 0; j < I18n::NumberOfLanguages; j++) { + if (strcmp(requestedLanguageId, I18n::translate(I18n::LanguageISO6391Names[j])) == 0) { + GlobalPreferences::sharedGlobalPreferences()->setLanguage((I18n::Language)j); break; } } diff --git a/apps/probability/calculation_cell.cpp b/apps/probability/calculation_cell.cpp index 1a3963bd9..3c2b3dc36 100644 --- a/apps/probability/calculation_cell.cpp +++ b/apps/probability/calculation_cell.cpp @@ -2,12 +2,10 @@ #include "responder_image_cell.h" #include #include +#include namespace Probability { -static inline KDCoordinate minCoordinate(KDCoordinate x, KDCoordinate y) { return x < y ? x : y; } -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } - CalculationCell::CalculationCell(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate) : m_text(KDFont::LargeFont, I18n::Message::Default, 0.5f, 0.5f), m_calculation(parentResponder, inputEventHandlerDelegate, textFieldDelegate), @@ -78,7 +76,7 @@ KDCoordinate CalculationCell::calculationCellWidth() const { KDCoordinate glyphWidth = KDFont::LargeFont->glyphSize().width(); KDCoordinate minTextFieldWidth = 4 * glyphWidth + TextCursorView::k_width; KDCoordinate maxTextFieldWidth = 14 * glyphWidth + TextCursorView::k_width; - return minCoordinate(maxTextFieldWidth, maxCoordinate(minTextFieldWidth, calculationCellWidth)); + return std::min(maxTextFieldWidth, std::max(minTextFieldWidth, calculationCellWidth)); } } diff --git a/apps/probability/calculation_controller.cpp b/apps/probability/calculation_controller.cpp index 704ed387f..5a954fd62 100644 --- a/apps/probability/calculation_controller.cpp +++ b/apps/probability/calculation_controller.cpp @@ -15,6 +15,7 @@ #include "images/focused_calcul4_icon.h" #include #include +#include #include using namespace Poincare; @@ -22,7 +23,7 @@ using namespace Shared; namespace Probability { -static inline int minInt(int x, int y) { return x < y ? x : y; } +constexpr int CalculationController::k_titleBufferSize; CalculationController::ContentView::ContentView(SelectableTableView * selectableTableView, Distribution * distribution, Calculation * calculation) : m_titleView(KDFont::SmallFont, I18n::Message::ComputeProbability, 0.5f, 0.5f, Palette::SecondaryText, Palette::BackgroundApps), @@ -293,7 +294,7 @@ void CalculationController::updateTitle() { } currentChar += UTF8Decoder::CodePointToChars(' ', m_titleBuffer + currentChar, k_titleBufferSize - currentChar); } - m_titleBuffer[minInt(currentChar, k_titleBufferSize) - 1] = 0; + m_titleBuffer[std::min(currentChar, k_titleBufferSize) - 1] = 0; } } diff --git a/apps/probability/distribution/binomial_distribution.cpp b/apps/probability/distribution/binomial_distribution.cpp index ed1e8f213..5ee9326e0 100644 --- a/apps/probability/distribution/binomial_distribution.cpp +++ b/apps/probability/distribution/binomial_distribution.cpp @@ -66,7 +66,7 @@ double BinomialDistribution::cumulativeDistributiveInverseForProbability(double } double BinomialDistribution::rightIntegralInverseForProbability(double * probability) { - if (m_parameter1 == 0.0 && (m_parameter2 == 0.0 || m_parameter2 == 1.0)) { + if (m_parameter1 == 0.0f && (m_parameter2 == 0.0f || m_parameter2 == 1.0f)) { return NAN; } if (*probability <= 0.0) { diff --git a/apps/probability/distribution/chi_squared_distribution.cpp b/apps/probability/distribution/chi_squared_distribution.cpp index 091cf30f2..9338c8c4b 100644 --- a/apps/probability/distribution/chi_squared_distribution.cpp +++ b/apps/probability/distribution/chi_squared_distribution.cpp @@ -1,11 +1,10 @@ #include "chi_squared_distribution.h" #include "regularized_gamma.h" #include +#include namespace Probability { -static inline double maxDouble(double x, double y) { return x > y ? x : y; } - float ChiSquaredDistribution::xMin() const { return -k_displayLeftMarginRatio * xMax(); } @@ -44,7 +43,7 @@ double ChiSquaredDistribution::cumulativeDistributiveFunctionAtAbscissa(double x return 0.0; } double result = 0.0; - if (regularizedGamma(m_parameter1/2.0, x/2.0, k_regularizedGammaPrecision, k_maxRegularizedGammaIterations, &result)) { + if (regularizedGamma(m_parameter1/2.0f, x/2.0, k_regularizedGammaPrecision, k_maxRegularizedGammaIterations, &result)) { return result; } return NAN; @@ -79,7 +78,7 @@ double ChiSquaredDistribution::cumulativeDistributiveInverseForProbability(doubl 2.0 * *probability * std::exp(std::lgamma(ceilKOver2)) / (exp(-kOver2Minus1) * std::pow(kOver2Minus1, kOver2Minus1)) : 30.0; // Ad hoc value xmax = std::isnan(xmax) ? 1000000000.0 : xmax; - return cumulativeDistributiveInverseForProbabilityUsingIncreasingFunctionRoot(probability, FLT_EPSILON, maxDouble(xMax(), xmax)); + return cumulativeDistributiveInverseForProbabilityUsingIncreasingFunctionRoot(probability, FLT_EPSILON, std::max(xMax(), xmax)); } } diff --git a/apps/probability/distribution/fisher_distribution.cpp b/apps/probability/distribution/fisher_distribution.cpp index 97e145599..66201ac0c 100644 --- a/apps/probability/distribution/fisher_distribution.cpp +++ b/apps/probability/distribution/fisher_distribution.cpp @@ -3,11 +3,10 @@ #include #include #include +#include namespace Probability { -static inline double maxDouble(double x, double y) { return x > y ? x : y; } - float FisherDistribution::xMin() const { return -k_displayLeftMarginRatio * xMax(); } @@ -74,7 +73,7 @@ double FisherDistribution::cumulativeDistributiveInverseForProbability(double * if (*probability < DBL_EPSILON) { return 0.0; } - return cumulativeDistributiveInverseForProbabilityUsingIncreasingFunctionRoot(probability, DBL_EPSILON, maxDouble(xMax(), 100.0)); // Ad-hoc value; + return cumulativeDistributiveInverseForProbabilityUsingIncreasingFunctionRoot(probability, DBL_EPSILON, std::max(xMax(), 100.0)); // Ad-hoc value; } float FisherDistribution::mode() const { diff --git a/apps/probability/distribution/student_distribution.cpp b/apps/probability/distribution/student_distribution.cpp index 4199f4467..a11640113 100644 --- a/apps/probability/distribution/student_distribution.cpp +++ b/apps/probability/distribution/student_distribution.cpp @@ -23,7 +23,7 @@ float StudentDistribution::evaluateAtAbscissa(float x) const { } bool StudentDistribution::authorizedValueAtIndex(float x, int index) const { - return x >= FLT_EPSILON && x <= 200.0; // We cannot draw the curve for x > 200 (coefficient() is too small) + return x >= FLT_EPSILON && x <= 200.0f; // We cannot draw the curve for x > 200 (coefficient() is too small) } double StudentDistribution::cumulativeDistributiveFunctionAtAbscissa(double x) const { @@ -55,7 +55,7 @@ double StudentDistribution::cumulativeDistributiveInverseForProbability(double * float StudentDistribution::lnCoefficient() const { const float k = m_parameter1; - return std::lgamma((k+1.0f)/2.0f) - std::lgamma(k/2.0f) - (M_PI+k)/2.0f; + return std::lgamma((k+1.0f)/2.0f) - std::lgamma(k/2.0f) - ((float)M_PI+k)/2.0f; } } diff --git a/apps/regression/calculation_controller.cpp b/apps/regression/calculation_controller.cpp index 878ea2c12..34b8e70ea 100644 --- a/apps/regression/calculation_controller.cpp +++ b/apps/regression/calculation_controller.cpp @@ -4,7 +4,7 @@ #include #include #include - +#include #include using namespace Poincare; @@ -12,8 +12,6 @@ using namespace Shared; namespace Regression { -static inline int maxInt(int x, int y) { return x > y ? x : y; } - CalculationController::CalculationController(Responder * parentResponder, ButtonRowController * header, Store * store) : TabTableController(parentResponder), ButtonRowDelegate(header, nullptr), @@ -375,7 +373,7 @@ int CalculationController::maxNumberOfCoefficients() const { int numberOfDefinedSeries = m_store->numberOfNonEmptySeries(); for (int i = 0; i < numberOfDefinedSeries; i++) { int currentNumberOfCoefs = m_store->modelForSeries(m_store->indexOfKthNonEmptySeries(i))->numberOfCoefficients(); - maxNumberCoefficients = maxInt(maxNumberCoefficients, currentNumberOfCoefs); + maxNumberCoefficients = std::max(maxNumberCoefficients, currentNumberOfCoefs); } return maxNumberCoefficients; } diff --git a/apps/regression/graph_controller.cpp b/apps/regression/graph_controller.cpp index ebdebbb46..f582d315e 100644 --- a/apps/regression/graph_controller.cpp +++ b/apps/regression/graph_controller.cpp @@ -4,14 +4,11 @@ #include "../apps_container.h" #include #include +#include using namespace Poincare; using namespace Shared; -static inline float minFloat(float x, float y) { return x < y ? x : y; } -static inline float maxFloat(float x, float y) { return x > y ? x : y; } -static inline int maxInt(int x, int y) { return x > y ? x : y; } - namespace Regression { GraphController::GraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, ButtonRowController * header, Store * store, CurveViewCursor * cursor, uint32_t * modelVersion, uint32_t * previousModelsVersions, uint32_t * rangeVersion, int * selectedDotIndex, int * selectedSeriesIndex) : @@ -165,7 +162,7 @@ void GraphController::reloadBannerView() { } if (!coefficientsAreDefined) { // Force the "Data not suitable" message to be on the next line - int numberOfCharToCompleteLine = maxInt(Ion::Display::Width / BannerView::Font()->glyphSize().width() - strlen(I18n::translate(formula)), 0); + int numberOfCharToCompleteLine = std::max(Ion::Display::Width / BannerView::Font()->glyphSize().width() - strlen(I18n::translate(formula)), 0); numberOfChar = 0; // Padding Shared::TextHelpers::PadWithSpaces(buffer, bufferSize, &numberOfChar, numberOfCharToCompleteLine - 1); @@ -390,8 +387,8 @@ InteractiveCurveViewRangeDelegate::Range GraphController::computeYRange(Interact for (int series = 0; series < Store::k_numberOfSeries; series++) { for (int k = 0; k < m_store->numberOfPairsOfSeries(series); k++) { if (m_store->xMin() <= m_store->get(series, 0, k) && m_store->get(series, 0, k) <= m_store->xMax()) { - minY = minFloat(minY, m_store->get(series, 1, k)); - maxY = maxFloat(maxY, m_store->get(series, 1, k)); + minY = std::min(minY, m_store->get(series, 1, k)); + maxY = std::max(maxY, m_store->get(series, 1, k)); } } } diff --git a/apps/regression/model/cubic_model.cpp b/apps/regression/model/cubic_model.cpp index 1c5899e81..42fdb5c7d 100644 --- a/apps/regression/model/cubic_model.cpp +++ b/apps/regression/model/cubic_model.cpp @@ -19,31 +19,29 @@ namespace Regression { Layout CubicModel::layout() { if (m_layout.isUninitialized()) { - constexpr int size = 15; - Layout layoutChildren[size] = { + m_layout = HorizontalLayout::Builder({ CodePointLayout::Builder('a', k_layoutFont), CodePointLayout::Builder(UCodePointMiddleDot, k_layoutFont), CodePointLayout::Builder('X', k_layoutFont), VerticalOffsetLayout::Builder( - CodePointLayout::Builder('3', k_layoutFont), - VerticalOffsetLayoutNode::Position::Superscript - ), + CodePointLayout::Builder('3', k_layoutFont), + VerticalOffsetLayoutNode::Position::Superscript + ), CodePointLayout::Builder('+', k_layoutFont), CodePointLayout::Builder('b', k_layoutFont), CodePointLayout::Builder(UCodePointMiddleDot, k_layoutFont), CodePointLayout::Builder('X', k_layoutFont), VerticalOffsetLayout::Builder( - CodePointLayout::Builder('2', k_layoutFont), - VerticalOffsetLayoutNode::Position::Superscript - ), + CodePointLayout::Builder('2', k_layoutFont), + VerticalOffsetLayoutNode::Position::Superscript + ), CodePointLayout::Builder('+', k_layoutFont), CodePointLayout::Builder('c', k_layoutFont), CodePointLayout::Builder(UCodePointMiddleDot, k_layoutFont), CodePointLayout::Builder('X', k_layoutFont), CodePointLayout::Builder('+', k_layoutFont), CodePointLayout::Builder('d', k_layoutFont), - }; - m_layout = HorizontalLayout::Builder(layoutChildren, size); + }); } return m_layout; } @@ -82,25 +80,28 @@ Expression CubicModel::expression(double * modelCoefficients) { double b = modelCoefficients[1]; double c = modelCoefficients[2]; double d = modelCoefficients[3]; - Expression addChildren[] = { - Multiplication::Builder( + // a*x^3+b*x^2+c*x+d + return Addition::Builder({ + Multiplication::Builder({ Number::DecimalNumber(a), Power::Builder( Symbol::Builder('x'), - Decimal::Builder(3.0))), - Multiplication::Builder( + Decimal::Builder(3.0) + ) + }), + Multiplication::Builder({ Number::DecimalNumber(b), Power::Builder( Symbol::Builder('x'), - Decimal::Builder(2.0))), - Multiplication::Builder( + Decimal::Builder(2.0) + ) + }), + Multiplication::Builder({ Number::DecimalNumber(c), - Symbol::Builder('x')), + Symbol::Builder('x') + }), Number::DecimalNumber(d) - }; - // a*x^3+b*x^2+c*x+d - Expression result = Addition::Builder(addChildren, 4); - return result; + }); } } diff --git a/apps/regression/model/exponential_model.cpp b/apps/regression/model/exponential_model.cpp index 608467a11..bffb66c53 100644 --- a/apps/regression/model/exponential_model.cpp +++ b/apps/regression/model/exponential_model.cpp @@ -13,21 +13,19 @@ namespace Regression { Layout ExponentialModel::layout() { if (m_layout.isUninitialized()) { - constexpr int size = 4; - Layout layoutChildren[size] = { + m_layout = HorizontalLayout::Builder({ CodePointLayout::Builder('a', k_layoutFont), CodePointLayout::Builder(UCodePointMiddleDot, k_layoutFont), CodePointLayout::Builder('e', k_layoutFont), VerticalOffsetLayout::Builder( - HorizontalLayout::Builder( - CodePointLayout::Builder('b', k_layoutFont), - CodePointLayout::Builder(UCodePointMiddleDot, k_layoutFont), - CodePointLayout::Builder('X', k_layoutFont) - ), - VerticalOffsetLayoutNode::Position::Superscript - ) - }; - m_layout = HorizontalLayout::Builder(layoutChildren, size); + HorizontalLayout::Builder({ + CodePointLayout::Builder('b', k_layoutFont), + CodePointLayout::Builder(UCodePointMiddleDot, k_layoutFont), + CodePointLayout::Builder('X', k_layoutFont) + }), + VerticalOffsetLayoutNode::Position::Superscript + ) + }); } return m_layout; } diff --git a/apps/regression/model/logarithmic_model.h b/apps/regression/model/logarithmic_model.h index a541b571d..0fd7048fa 100644 --- a/apps/regression/model/logarithmic_model.h +++ b/apps/regression/model/logarithmic_model.h @@ -16,7 +16,7 @@ public: int numberOfCoefficients() const override { return 2; } int bannerLinesCount() const override { return 2; } protected: - virtual bool dataSuitableForFit(Store * store, int series) const override; + bool dataSuitableForFit(Store * store, int series) const override; }; } diff --git a/apps/regression/model/logistic_model.cpp b/apps/regression/model/logistic_model.cpp index f74db8f3d..0876aa70d 100644 --- a/apps/regression/model/logistic_model.cpp +++ b/apps/regression/model/logistic_model.cpp @@ -13,29 +13,25 @@ namespace Regression { Layout LogisticModel::layout() { if (m_layout.isUninitialized()) { - constexpr int exponentSize = 4; - Layout exponentLayoutChildren[exponentSize] = { - CodePointLayout::Builder('-', k_layoutFont), - CodePointLayout::Builder('b', k_layoutFont), - CodePointLayout::Builder(UCodePointMiddleDot, k_layoutFont), - CodePointLayout::Builder('X', k_layoutFont) - }; - constexpr int denominatorSize = 6; - Layout layoutChildren[denominatorSize] = { - CodePointLayout::Builder('1', k_layoutFont), - CodePointLayout::Builder('+', k_layoutFont), - CodePointLayout::Builder('a', k_layoutFont), - CodePointLayout::Builder(UCodePointMiddleDot, k_layoutFont), - CodePointLayout::Builder('e', k_layoutFont), - VerticalOffsetLayout::Builder( - HorizontalLayout::Builder(exponentLayoutChildren, exponentSize), + m_layout = FractionLayout::Builder( + CodePointLayout::Builder('c', k_layoutFont), + HorizontalLayout::Builder({ + CodePointLayout::Builder('1', k_layoutFont), + CodePointLayout::Builder('+', k_layoutFont), + CodePointLayout::Builder('a', k_layoutFont), + CodePointLayout::Builder(UCodePointMiddleDot, k_layoutFont), + CodePointLayout::Builder('e', k_layoutFont), + VerticalOffsetLayout::Builder( + HorizontalLayout::Builder({ + CodePointLayout::Builder('-', k_layoutFont), + CodePointLayout::Builder('b', k_layoutFont), + CodePointLayout::Builder(UCodePointMiddleDot, k_layoutFont), + CodePointLayout::Builder('X', k_layoutFont) + }), VerticalOffsetLayoutNode::Position::Superscript ) - }; - m_layout = FractionLayout::Builder( - CodePointLayout::Builder('c', k_layoutFont), - HorizontalLayout::Builder(layoutChildren, denominatorSize) - ); + }) + ); } return m_layout; } diff --git a/apps/regression/model/power_model.cpp b/apps/regression/model/power_model.cpp index c152c9c1d..b7c0e09e0 100644 --- a/apps/regression/model/power_model.cpp +++ b/apps/regression/model/power_model.cpp @@ -12,17 +12,15 @@ namespace Regression { Layout PowerModel::layout() { if (m_layout.isUninitialized()) { - constexpr int size = 4; - Layout layoutChildren[size] = { + m_layout = HorizontalLayout::Builder({ CodePointLayout::Builder('a', k_layoutFont), CodePointLayout::Builder(UCodePointMiddleDot, k_layoutFont), CodePointLayout::Builder('X', k_layoutFont), VerticalOffsetLayout::Builder( - CodePointLayout::Builder('b', k_layoutFont), - VerticalOffsetLayoutNode::Position::Superscript - ), - }; - m_layout = HorizontalLayout::Builder(layoutChildren, size); + CodePointLayout::Builder('b', k_layoutFont), + VerticalOffsetLayoutNode::Position::Superscript + ), + }); } return m_layout; } diff --git a/apps/regression/model/quadratic_model.cpp b/apps/regression/model/quadratic_model.cpp index 67305337f..66bc7cf0c 100644 --- a/apps/regression/model/quadratic_model.cpp +++ b/apps/regression/model/quadratic_model.cpp @@ -19,23 +19,21 @@ namespace Regression { Layout QuadraticModel::layout() { if (m_layout.isUninitialized()) { - constexpr int size = 10; - Layout layoutChildren[size] = { + m_layout = HorizontalLayout::Builder({ CodePointLayout::Builder('a', k_layoutFont), CodePointLayout::Builder(UCodePointMiddleDot, k_layoutFont), CodePointLayout::Builder('X', k_layoutFont), VerticalOffsetLayout::Builder( - CodePointLayout::Builder('2', k_layoutFont), - VerticalOffsetLayoutNode::Position::Superscript - ), + CodePointLayout::Builder('2', k_layoutFont), + VerticalOffsetLayoutNode::Position::Superscript + ), CodePointLayout::Builder('+', k_layoutFont), CodePointLayout::Builder('b', k_layoutFont), CodePointLayout::Builder(UCodePointMiddleDot, k_layoutFont), CodePointLayout::Builder('X', k_layoutFont), CodePointLayout::Builder('+', k_layoutFont), CodePointLayout::Builder('c', k_layoutFont), - }; - m_layout = HorizontalLayout::Builder(layoutChildren, size); + }); } return m_layout; } @@ -69,19 +67,20 @@ Expression QuadraticModel::expression(double * modelCoefficients) { double b = modelCoefficients[1]; double c = modelCoefficients[2]; // a*x^2+b*x+c - Expression addChildren[] = { - Multiplication::Builder( + return Addition::Builder({ + Multiplication::Builder({ Number::DecimalNumber(a), Power::Builder( Symbol::Builder('x'), - Decimal::Builder(2.0))), - Multiplication::Builder( + Decimal::Builder(2.0) + ) + }), + Multiplication::Builder({ Number::DecimalNumber(b), - Symbol::Builder('x')), + Symbol::Builder('x') + }), Number::DecimalNumber(c) - }; - Expression result = Addition::Builder(addChildren, 3); - return result; + }); } } diff --git a/apps/regression/model/quartic_model.cpp b/apps/regression/model/quartic_model.cpp index 32a2323a8..2b37e4423 100644 --- a/apps/regression/model/quartic_model.cpp +++ b/apps/regression/model/quartic_model.cpp @@ -19,39 +19,37 @@ namespace Regression { Layout QuarticModel::layout() { if (m_layout.isUninitialized()) { - constexpr int size = 20; - Layout layoutChildren[size] = { + m_layout = HorizontalLayout::Builder({ CodePointLayout::Builder('a', k_layoutFont), CodePointLayout::Builder(UCodePointMiddleDot, k_layoutFont), CodePointLayout::Builder('X', k_layoutFont), VerticalOffsetLayout::Builder( - CodePointLayout::Builder('4', k_layoutFont), - VerticalOffsetLayoutNode::Position::Superscript - ), + CodePointLayout::Builder('4', k_layoutFont), + VerticalOffsetLayoutNode::Position::Superscript + ), CodePointLayout::Builder('+', k_layoutFont), CodePointLayout::Builder('b', k_layoutFont), CodePointLayout::Builder(UCodePointMiddleDot, k_layoutFont), CodePointLayout::Builder('X', k_layoutFont), VerticalOffsetLayout::Builder( - CodePointLayout::Builder('3', k_layoutFont), - VerticalOffsetLayoutNode::Position::Superscript - ), + CodePointLayout::Builder('3', k_layoutFont), + VerticalOffsetLayoutNode::Position::Superscript + ), CodePointLayout::Builder('+', k_layoutFont), CodePointLayout::Builder('c', k_layoutFont), CodePointLayout::Builder(UCodePointMiddleDot, k_layoutFont), CodePointLayout::Builder('X', k_layoutFont), VerticalOffsetLayout::Builder( - CodePointLayout::Builder('2', k_layoutFont), - VerticalOffsetLayoutNode::Position::Superscript - ), + CodePointLayout::Builder('2', k_layoutFont), + VerticalOffsetLayoutNode::Position::Superscript + ), CodePointLayout::Builder('+', k_layoutFont), CodePointLayout::Builder('d', k_layoutFont), CodePointLayout::Builder(UCodePointMiddleDot, k_layoutFont), CodePointLayout::Builder('X', k_layoutFont), CodePointLayout::Builder('+', k_layoutFont), CodePointLayout::Builder('e', k_layoutFont), - }; - m_layout = HorizontalLayout::Builder(layoutChildren, size); + }); } return m_layout; } @@ -96,34 +94,35 @@ Expression QuarticModel::expression(double * modelCoefficients) { double c = modelCoefficients[2]; double d = modelCoefficients[3]; double e = modelCoefficients[4]; - Expression addChildren[] = { - // a*x^4 - Multiplication::Builder( + // a*x^4+b*x^3+c*x^2+d*x+e + return Addition::Builder({ + Multiplication::Builder({ Number::DecimalNumber(a), Power::Builder( Symbol::Builder('x'), - Decimal::Builder(4.0))), - // b*x^3 - Multiplication::Builder( + Decimal::Builder(4.0) + ) + }), + Multiplication::Builder({ Number::DecimalNumber(b), Power::Builder( Symbol::Builder('x'), - Decimal::Builder(3.0))), - // c*x^2 - Multiplication::Builder( + Decimal::Builder(3.0) + ) + }), + Multiplication::Builder({ Number::DecimalNumber(c), Power::Builder( Symbol::Builder('x'), - Decimal::Builder(2.0))), - // d*x - Multiplication::Builder( + Decimal::Builder(2.0) + ) + }), + Multiplication::Builder({ Number::DecimalNumber(d), - Symbol::Builder('x')), - // e + Symbol::Builder('x') + }), Number::DecimalNumber(e) - }; - Expression result = Addition::Builder(addChildren, 5); - return result; + }); } } diff --git a/apps/regression/store.cpp b/apps/regression/store.cpp index 98f703bd5..e7d827cb2 100644 --- a/apps/regression/store.cpp +++ b/apps/regression/store.cpp @@ -5,14 +5,12 @@ #include #include #include +#include using namespace Shared; namespace Regression { -static inline float maxFloat(float x, float y) { return x > y ? x : y; } -static inline float minFloat(float x, float y) { return x < y ? x : y; } - static_assert(Model::k_numberOfModels == 9, "Number of models changed, Regression::Store() needs to adapt"); static_assert(Store::k_numberOfSeries == 3, "Number of series changed, Regression::Store() needs to adapt (m_seriesChecksum)"); @@ -146,8 +144,8 @@ void Store::setDefault() { float maxX = -FLT_MAX; for (int series = 0; series < k_numberOfSeries; series++) { if (!seriesIsEmpty(series)) { - minX = minFloat(minX, minValueOfColumn(series, 0)); - maxX = maxFloat(maxX, maxValueOfColumn(series, 0)); + minX = std::min(minX, minValueOfColumn(series, 0)); + maxX = std::max(maxX, maxValueOfColumn(series, 0)); } } float range = maxX - minX; @@ -199,7 +197,7 @@ void Store::resetMemoization() { float Store::maxValueOfColumn(int series, int i) const { float maxColumn = -FLT_MAX; for (int k = 0; k < numberOfPairsOfSeries(series); k++) { - maxColumn = maxFloat(maxColumn, m_data[series][i][k]); + maxColumn = std::max(maxColumn, m_data[series][i][k]); } return maxColumn; } @@ -207,7 +205,7 @@ float Store::maxValueOfColumn(int series, int i) const { float Store::minValueOfColumn(int series, int i) const { float minColumn = FLT_MAX; for (int k = 0; k < numberOfPairsOfSeries(series); k++) { - minColumn = minFloat(minColumn, m_data[series][i][k]); + minColumn = std::min(minColumn, m_data[series][i][k]); } return minColumn; } diff --git a/apps/rpn b/apps/rpn index 8bc648eb4..344fc1f7b 160000 --- a/apps/rpn +++ b/apps/rpn @@ -1 +1 @@ -Subproject commit 8bc648eb4034107848d96e508070b88951920313 +Subproject commit 344fc1f7b6689c71466b53c675383d5fd2496af5 diff --git a/apps/sequence/graph/curve_view_range.cpp b/apps/sequence/graph/curve_view_range.cpp index 85c828d86..a4374164d 100644 --- a/apps/sequence/graph/curve_view_range.cpp +++ b/apps/sequence/graph/curve_view_range.cpp @@ -2,14 +2,13 @@ #include #include #include +#include using namespace Shared; using namespace Poincare; namespace Sequence { -static inline float maxFloat(float x, float y) { return x > y ? x : y; } - CurveViewRange::CurveViewRange(InteractiveCurveViewRangeDelegate * delegate) : InteractiveCurveViewRange(delegate) { @@ -37,7 +36,7 @@ void CurveViewRange::normalize() { float xMean = xCenter(); float yMean = yCenter(); - const float unit = maxFloat(xGridUnit(), yGridUnit()); + const float unit = std::max(xGridUnit(), yGridUnit()); // Compute the X const float newXHalfRange = NormalizedXHalfRange(unit); diff --git a/apps/sequence/graph/graph_controller.cpp b/apps/sequence/graph/graph_controller.cpp index 8e14c64c8..d35077101 100644 --- a/apps/sequence/graph/graph_controller.cpp +++ b/apps/sequence/graph/graph_controller.cpp @@ -2,15 +2,13 @@ #include #include #include "../app.h" +#include using namespace Shared; using namespace Poincare; namespace Sequence { -static inline int minInt(int x, int y) { return (x < y ? x : y); } -static inline int maxInt(int x, int y) { return (x > y ? x : y); } - GraphController::GraphController(Responder * parentResponder, ::InputEventHandlerDelegate * inputEventHandlerDelegate, SequenceStore * sequenceStore, CurveViewRange * graphRange, CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * previousModelsVersions, uint32_t * rangeVersion, Preferences::AngleUnit * angleUnitVersion, ButtonRowController * header) : FunctionGraphController(parentResponder, inputEventHandlerDelegate, header, graphRange, &m_view, cursor, indexFunctionSelectedByCursor, modelVersion, previousModelsVersions, rangeVersion, angleUnitVersion), m_bannerView(this, inputEventHandlerDelegate, this), @@ -39,7 +37,7 @@ float GraphController::interestingXMin() const { int nbOfActiveModels = functionStore()->numberOfActiveFunctions(); for (int i = 0; i < nbOfActiveModels; i++) { Sequence * s = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(i)); - nmin = minInt(nmin, s->initialRank()); + nmin = std::min(nmin, s->initialRank()); } assert(nmin < INT_MAX); return nmin; @@ -53,8 +51,8 @@ float GraphController::interestingXHalfRange() const { for (int i = 0; i < nbOfActiveModels; i++) { Sequence * s = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(i)); int firstInterestingIndex = s->initialRank(); - nmin = minInt(nmin, firstInterestingIndex); - nmax = maxInt(nmax, firstInterestingIndex + standardRange); + nmin = std::min(nmin, firstInterestingIndex); + nmax = std::max(nmax, firstInterestingIndex + static_cast(standardRange)); } assert(nmax - nmin >= standardRange); return nmax - nmin; diff --git a/apps/sequence/list/list_controller.cpp b/apps/sequence/list/list_controller.cpp index 8b97f791b..48e59d38a 100644 --- a/apps/sequence/list/list_controller.cpp +++ b/apps/sequence/list/list_controller.cpp @@ -1,12 +1,11 @@ #include "list_controller.h" #include "../app.h" #include +#include using namespace Shared; using namespace Poincare; -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } - namespace Sequence { ListController::ListController(Responder * parentResponder, ::InputEventHandlerDelegate * inputEventHandlerDelegate, ButtonRowController * header, ButtonRowController * footer) : @@ -55,7 +54,7 @@ KDCoordinate ListController::expressionRowHeight(int j) { return defaultHeight; } KDCoordinate sequenceHeight = layout.layoutSize().height(); - return maxCoordinate(defaultHeight, sequenceHeight + 2*k_expressionCellVerticalMargin); + return std::max(defaultHeight, sequenceHeight + 2*k_expressionCellVerticalMargin); } void ListController::willDisplayCellAtLocation(HighlightCell * cell, int i, int j) { diff --git a/apps/settings/base.de.i18n b/apps/settings/base.de.i18n index aa2e32d5f..724992707 100644 --- a/apps/settings/base.de.i18n +++ b/apps/settings/base.de.i18n @@ -7,7 +7,7 @@ EditionLinear = "Linear " Edition2D = "Natürlich " ComplexFormat = "Komplex" ExamMode = "Prüfungsmodus" -ExamModeActive = "Wieder starten Modus" +ExamModeActive = "Modus erneut starten" ToDeactivateExamMode1 = "Um den Prüfungsmodus auszuschalten," ToDeactivateExamMode2 = "schließen Sie den Rechner an einen" ToDeactivateExamMode3 = "Computer oder eine Steckdose an." diff --git a/apps/settings/sub_menu/preferences_controller.cpp b/apps/settings/sub_menu/preferences_controller.cpp index c0b4b973d..b99573195 100644 --- a/apps/settings/sub_menu/preferences_controller.cpp +++ b/apps/settings/sub_menu/preferences_controller.cpp @@ -7,13 +7,12 @@ #include #include #include +#include using namespace Poincare; namespace Settings { -static inline int maxInt(int x, int y) { return x > y ? x : y; } - PreferencesController::PreferencesController(Responder * parentResponder) : GenericSubController(parentResponder) { @@ -233,7 +232,7 @@ void PreferencesController::setPreferenceWithValueIndex(I18n::Message message, i /* In Engineering mode, the number of significant digits cannot be lower * than 3, because we need to be able to display 100 for instance. */ // TODO: Add warning about signifiant digits change ? - preferences->setNumberOfSignificantDigits(maxInt(preferences->numberOfSignificantDigits(), 3)); + preferences->setNumberOfSignificantDigits(std::max(preferences->numberOfSignificantDigits(), 3)); } } else if (message == I18n::Message::EditionMode) { preferences->setEditionMode((Preferences::EditionMode)valueIndex); diff --git a/apps/settings/sub_menu/selectable_view_with_messages.cpp b/apps/settings/sub_menu/selectable_view_with_messages.cpp index 5bef3ecc9..8e64acce4 100644 --- a/apps/settings/sub_menu/selectable_view_with_messages.cpp +++ b/apps/settings/sub_menu/selectable_view_with_messages.cpp @@ -1,13 +1,12 @@ #include "selectable_view_with_messages.h" #include #include +#include using namespace Shared; namespace Settings { -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } - SelectableViewWithMessages::SelectableViewWithMessages(SelectableTableView * selectableTableView) : m_selectableTableView(selectableTableView), m_numberOfMessages(0) @@ -52,7 +51,7 @@ void SelectableViewWithMessages::layoutSubviews(bool force) { // Layout the text KDCoordinate textHeight = KDFont::SmallFont->glyphSize().height(); - KDCoordinate defOrigin = maxCoordinate(bounds().height() - Metric::CommonBottomMargin - m_numberOfMessages*textHeight, tableHeight); + KDCoordinate defOrigin = std::max(bounds().height() - Metric::CommonBottomMargin - m_numberOfMessages*textHeight, tableHeight); for (int i = 0; i < m_numberOfMessages; i++) { m_messageLines[i].setFrame(KDRect(0, defOrigin, bounds().width(), textHeight), force); diff --git a/apps/shared/continuous_function.cpp b/apps/shared/continuous_function.cpp index fdb4fd2cc..ebac4e160 100644 --- a/apps/shared/continuous_function.cpp +++ b/apps/shared/continuous_function.cpp @@ -14,14 +14,12 @@ #include #include #include +#include using namespace Poincare; namespace Shared { -static inline double maxDouble(double x, double y) { return x > y ? x : y; } -static inline double minDouble(double x, double y) { return x < y ? x : y; } - void ContinuousFunction::DefaultName(char buffer[], size_t bufferSize) { constexpr int k_maxNumberOfDefaultLetterNames = 4; static constexpr const char k_defaultLetterNames[k_maxNumberOfDefaultLetterNames] = { @@ -312,14 +310,14 @@ Coordinate2D ContinuousFunction::nextIntersectionFrom(double start, doub constexpr int bufferSize = CodePoint::MaxCodePointCharLength + 1; char unknownX[bufferSize]; SerializationHelper::CodePoint(unknownX, bufferSize, UCodePointUnknown); - double domainMin = maxDouble(tMin(), eDomainMin); - double domainMax = minDouble(tMax(), eDomainMax); + double domainMin = std::max(tMin(), eDomainMin); + double domainMax = std::min(tMax(), eDomainMax); if (step > 0.0f) { - start = maxDouble(start, domainMin); - max = minDouble(max, domainMax); + start = std::max(start, domainMin); + max = std::min(max, domainMax); } else { - start = minDouble(start, domainMax); - max = maxDouble(max, domainMin); + start = std::min(start, domainMax); + max = std::max(max, domainMin); } return PoincareHelpers::NextIntersection(expressionReduced(context), unknownX, start, step, max, context, e); } @@ -330,19 +328,19 @@ Coordinate2D ContinuousFunction::nextPointOfInterestFrom(double start, d char unknownX[bufferSize]; SerializationHelper::CodePoint(unknownX, bufferSize, UCodePointUnknown); if (step > 0.0f) { - start = maxDouble(start, tMin()); - max = minDouble(max, tMax()); + start = std::max(start, tMin()); + max = std::min(max, tMax()); } else { - start = minDouble(start, tMax()); - max = maxDouble(max, tMin()); + start = std::min(start, tMax()); + max = std::max(max, tMin()); } return compute(expressionReduced(context), unknownX, start, step, max, context); } Poincare::Expression ContinuousFunction::sumBetweenBounds(double start, double end, Poincare::Context * context) const { assert(plotType() == PlotType::Cartesian); - start = maxDouble(start, tMin()); - end = minDouble(end, tMax()); + start = std::max(start, tMin()); + end = std::min(end, tMax()); return Poincare::Integral::Builder(expressionReduced(context).clone(), Poincare::Symbol::Builder(UCodePointUnknown), 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 diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index f7f0a747c..89065ac6a 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -11,11 +12,6 @@ using namespace Poincare; namespace Shared { -static inline int minInt(int x, int y) { return x < y ? x : y; } - -static inline float minFloat(float x, float y) { return x < y ? x : y; } -static inline float maxFloat(float x, float y) { return x > y ? x : y; } - CurveView::CurveView(CurveViewRange * curveViewRange, CurveViewCursor * curveViewCursor, BannerView * bannerView, CursorView * cursorView, View * okView, bool displayBanner) : View(), @@ -182,8 +178,8 @@ void CurveView::computeLabels(Axis axis) { * them from overprinting one another.*/ int labelMaxGlyphLength = labelMaxGlyphLengthSize(); if (axis == Axis::Horizontal) { - float pixelsPerLabel = maxFloat(0.0f, ((float)Ion::Display::Width)/((float)axisLabelsCount) - k_labelMargin); - labelMaxGlyphLength = minInt(labelMaxGlyphLengthSize(), pixelsPerLabel/k_font->glyphSize().width()); + float pixelsPerLabel = std::max(0.0f, ((float)Ion::Display::Width)/((float)axisLabelsCount) - k_labelMargin); + labelMaxGlyphLength = std::min(labelMaxGlyphLengthSize(), pixelsPerLabel/k_font->glyphSize().width()); } if (labelValue < step && labelValue > -step) { @@ -590,7 +586,7 @@ void CurveView::drawCurve(KDContext * ctx, KDRect rect, float tStart, float tEnd x = xy.x1(); y = xy.x2(); if (colorUnderCurve && !std::isnan(x) && colorLowerBound < x && x < colorUpperBound && !(std::isnan(y) || std::isinf(y))) { - drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, x, minFloat(0.0f, y), maxFloat(0.0f, y), color, 1); + drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, x, std::min(0.0f, y), std::max(0.0f, y), color, 1); } joinDots(ctx, rect, xyEvaluation, model, context, drawStraightLinesEarly, previousT, previousX, previousY, t, x, y, color, thick, k_maxNumberOfIterations); } while (true); @@ -599,8 +595,8 @@ void CurveView::drawCurve(KDContext * ctx, KDRect rect, float tStart, float tEnd void CurveView::drawCartesianCurve(KDContext * ctx, KDRect rect, float xMin, float xMax, EvaluateXYForParameter xyEvaluation, void * model, void * context, KDColor color, bool thick, bool colorUnderCurve, float colorLowerBound, float colorUpperBound) const { float rectLeft = pixelToFloat(Axis::Horizontal, rect.left() - k_externRectMargin); float rectRight = pixelToFloat(Axis::Horizontal, rect.right() + k_externRectMargin); - float tStart = std::isnan(rectLeft) ? xMin : maxFloat(xMin, rectLeft); - float tEnd = std::isnan(rectRight) ? xMax : minFloat(xMax, rectRight); + float tStart = std::isnan(rectLeft) ? xMin : std::max(xMin, rectLeft); + float tEnd = std::isnan(rectRight) ? xMax : std::min(xMax, rectRight); assert(!std::isnan(tStart) && !std::isnan(tEnd)); if (std::isinf(tStart) || std::isinf(tEnd) || tStart > tEnd) { return; @@ -701,8 +697,8 @@ static void clipBarycentricCoordinatesBetweenBounds(float & start, float & end, end = 0; } } else { - start = maxFloat(start, (bounds[(p1f > p2f) ? lower : upper] - p2f)/(p1f-p2f)); - end = minFloat( end , (bounds[(p1f > p2f) ? upper : lower] - p2f)/(p1f-p2f)); + start = std::max(start, (bounds[(p1f > p2f) ? lower : upper] - p2f)/(p1f-p2f)); + end = std::min( end , (bounds[(p1f > p2f) ? upper : lower] - p2f)/(p1f-p2f)); } } diff --git a/apps/shared/editable_cell_table_view_controller.cpp b/apps/shared/editable_cell_table_view_controller.cpp index 6c00a76f8..48365a3f5 100644 --- a/apps/shared/editable_cell_table_view_controller.cpp +++ b/apps/shared/editable_cell_table_view_controller.cpp @@ -3,11 +3,10 @@ #include "../constant.h" #include #include +#include using namespace Poincare; -static inline int maxInt(int x, int y) { return x > y ? x : y; } - namespace Shared { EditableCellTableViewController::EditableCellTableViewController(Responder * parentResponder) : @@ -60,7 +59,7 @@ bool EditableCellTableViewController::textFieldDidFinishEditing(TextField * text int EditableCellTableViewController::numberOfRows() const { int numberOfModelElements = 0; for (int i = 0; i < numberOfColumns(); i++) { - numberOfModelElements = maxInt(numberOfModelElements, numberOfElementsInColumn(i)); + numberOfModelElements = std::max(numberOfModelElements, numberOfElementsInColumn(i)); } return 1 + numberOfModelElements + (numberOfModelElements < maxNumberOfElements()); } diff --git a/apps/shared/expiring_pointer.h b/apps/shared/expiring_pointer.h index 7184aab50..4dd7dd06b 100644 --- a/apps/shared/expiring_pointer.h +++ b/apps/shared/expiring_pointer.h @@ -11,31 +11,31 @@ class ExpiringPointer { friend class ExpiringPointer; public: ExpiringPointer(T * rawPointer) : m_rawPointer(rawPointer) { -#if DEBUG +#ifndef NDEBUG s_global = rawPointer; #endif } T * pointer() { return m_rawPointer; } T *operator->() { -#if DEBUG +#ifndef NDEBUG assert(m_rawPointer != nullptr && m_rawPointer == s_global); #endif return m_rawPointer; } T &operator*() { -#if DEBUG +#ifndef NDEBUG assert(m_rawPointer != nullptr && m_rawPointer == s_global); #endif return *m_rawPointer; } private: -#if DEBUG +#ifndef NDEBUG static T * s_global; #endif T * m_rawPointer; }; -#if DEBUG +#ifndef NDEBUG template T * ExpiringPointer::s_global = nullptr; #endif diff --git a/apps/shared/expression_field_delegate_app.h b/apps/shared/expression_field_delegate_app.h index 1c73f1c7e..0e1752813 100644 --- a/apps/shared/expression_field_delegate_app.h +++ b/apps/shared/expression_field_delegate_app.h @@ -10,7 +10,7 @@ class ExpressionFieldDelegateApp : public TextFieldDelegateApp, public LayoutFie public: virtual ~ExpressionFieldDelegateApp() = default; bool layoutFieldShouldFinishEditing(LayoutField * layoutField, Ion::Events::Event event) override; - virtual bool layoutFieldDidReceiveEvent(LayoutField * layoutField, Ion::Events::Event event) override; + bool layoutFieldDidReceiveEvent(LayoutField * layoutField, Ion::Events::Event event) override; protected: ExpressionFieldDelegateApp(Snapshot * snapshot, ViewController * rootViewController); }; diff --git a/apps/shared/expression_model.cpp b/apps/shared/expression_model.cpp index cf698f7c2..307956e02 100644 --- a/apps/shared/expression_model.cpp +++ b/apps/shared/expression_model.cpp @@ -7,14 +7,13 @@ #include #include #include +#include using namespace Ion; using namespace Poincare; namespace Shared { -static inline int maxInt(int x, int y) { return x > y ? x : y; } - ExpressionModel::ExpressionModel() : m_expression(), m_layout(), @@ -126,7 +125,7 @@ Ion::Storage::Record::ErrorStatus ExpressionModel::setExpressionContent(Ion::Sto size_t newDataSize = previousDataSize - previousExpressionSize + newExpressionSize; void * expAddress = expressionAddress(record); // Update size of record to maximal size between previous and new data - newData.size = maxInt(previousDataSize, newDataSize); + newData.size = std::max(previousDataSize, newDataSize); Ion::Storage::Record::ErrorStatus error = record->setValue(newData); if (error != Ion::Storage::Record::ErrorStatus::None) { assert(error == Ion::Storage::Record::ErrorStatus::NotEnoughSpaceAvailable); diff --git a/apps/shared/expression_model_list_controller.cpp b/apps/shared/expression_model_list_controller.cpp index e656ba069..dc1c18d0f 100644 --- a/apps/shared/expression_model_list_controller.cpp +++ b/apps/shared/expression_model_list_controller.cpp @@ -1,11 +1,10 @@ #include "expression_model_list_controller.h" #include #include +#include namespace Shared { -static inline int minInt(int x, int y) { return x < y ? x : y; } - /* Table Data Source */ ExpressionModelListController::ExpressionModelListController(Responder * parentResponder, I18n::Message text) : @@ -121,7 +120,7 @@ int ExpressionModelListController::memoizedIndexFromCumulatedHeight(KDCoordinate KDCoordinate currentCumulatedHeight = memoizedCumulatedHeightFromIndex(currentSelectedRow); if (offsetY > currentCumulatedHeight) { - int iMax = minInt(k_memoizedCellsCount/2 + 1, rowsCount - currentSelectedRow); + int iMax = std::min(k_memoizedCellsCount/2 + 1, rowsCount - currentSelectedRow); for (int i = 0; i < iMax; i++) { currentCumulatedHeight+= memoizedRowHeight(currentSelectedRow + i); if (offsetY <= currentCumulatedHeight) { @@ -129,7 +128,7 @@ int ExpressionModelListController::memoizedIndexFromCumulatedHeight(KDCoordinate } } } else { - int iMax = minInt(k_memoizedCellsCount/2, currentSelectedRow); + int iMax = std::min(k_memoizedCellsCount/2, currentSelectedRow); for (int i = 1; i <= iMax; i++) { currentCumulatedHeight-= memoizedRowHeight(currentSelectedRow-i); if (offsetY > currentCumulatedHeight) { diff --git a/apps/shared/function_graph_controller.cpp b/apps/shared/function_graph_controller.cpp index e1922ef6b..21b3c652b 100644 --- a/apps/shared/function_graph_controller.cpp +++ b/apps/shared/function_graph_controller.cpp @@ -5,16 +5,12 @@ #include #include #include +#include using namespace Poincare; namespace Shared { -static inline float minFloat(float x, float y) { return x < y ? x : y; } -static inline float maxFloat(float x, float y) { return x > y ? x : y; } -static inline double minDouble(double x, double y) { return x < y ? x : y; } -static inline double maxDouble(double x, double y) { return x > y ? x : y; } - FunctionGraphController::FunctionGraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, ButtonRowController * header, InteractiveCurveViewRange * interactiveRange, CurveView * curveView, CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * previousModelsVersions, uint32_t * rangeVersion, Preferences::AngleUnit * angleUnitVersion) : InteractiveCurveViewController(parentResponder, inputEventHandlerDelegate, header, interactiveRange, curveView, cursor, modelVersion, previousModelsVersions, rangeVersion), m_initialisationParameterController(this, interactiveRange), @@ -92,13 +88,13 @@ InteractiveCurveViewRangeDelegate::Range FunctionGraphController::computeYRange( if (std::isnan(tMin)) { tMin = xMin; } else if (f->shouldClipTRangeToXRange()) { - tMin = maxFloat(tMin, xMin); + tMin = std::max(tMin, xMin); } double tMax = f->tMax(); if (std::isnan(tMax)) { tMax = xMax; } else if (f->shouldClipTRangeToXRange()) { - tMax = minFloat(tMax, xMax); + tMax = std::min(tMax, xMax); } /* In practice, a step smaller than a pixel's width is needed for sampling * the values of a function. Otherwise some relevant extremal values may be @@ -113,8 +109,8 @@ InteractiveCurveViewRangeDelegate::Range FunctionGraphController::computeYRange( if (!std::isnan(x) && !std::isinf(x) && x >= xMin && x <= xMax) { float y = xy.x2(); if (!std::isnan(y) && !std::isinf(y)) { - min = minFloat(min, y); - max = maxFloat(max, y); + min = std::min(min, y); + max = std::max(max, y); } } } @@ -167,7 +163,7 @@ bool FunctionGraphController::moveCursorVertically(int direction) { double clippedT = m_cursor->t(); if (!std::isnan(f->tMin())) { assert(!std::isnan(f->tMax())); - clippedT = minDouble(f->tMax(), maxDouble(f->tMin(), clippedT)); + clippedT = std::min(f->tMax(), std::max(f->tMin(), clippedT)); } Poincare::Coordinate2D cursorPosition = f->evaluateXYAtParameter(clippedT, context); m_cursor->moveTo(clippedT, cursorPosition.x1(), cursorPosition.x2()); diff --git a/apps/shared/function_graph_view.cpp b/apps/shared/function_graph_view.cpp index 36e435a3a..cc8a532bf 100644 --- a/apps/shared/function_graph_view.cpp +++ b/apps/shared/function_graph_view.cpp @@ -69,8 +69,8 @@ void FunctionGraphView::reloadBetweenBounds(float start, float end) { if (start == end) { return; } - float pixelLowerBound = floatToPixel(Axis::Horizontal, start)-2.0; - float pixelUpperBound = floatToPixel(Axis::Horizontal, end)+4.0; + float pixelLowerBound = floatToPixel(Axis::Horizontal, start) - 2.0f; + float pixelUpperBound = floatToPixel(Axis::Horizontal, end) + 4.0f; /* We exclude the banner frame from the dirty zone to avoid unnecessary * redrawing */ KDRect dirtyZone(KDRect(pixelLowerBound, 0, pixelUpperBound-pixelLowerBound, diff --git a/apps/shared/function_list_controller.cpp b/apps/shared/function_list_controller.cpp index f16138477..d8dbf2ad7 100644 --- a/apps/shared/function_list_controller.cpp +++ b/apps/shared/function_list_controller.cpp @@ -1,10 +1,11 @@ #include "function_list_controller.h" #include "function_app.h" #include "function_expression_cell.h" +#include namespace Shared { -static inline int maxInt(int x, int y) { return x > y ? x : y; } +constexpr KDCoordinate FunctionListController::k_minTitleColumnWidth; FunctionListController::FunctionListController(Responder * parentResponder, ButtonRowController * header, ButtonRowController * footer, I18n::Message text) : ExpressionModelListController(parentResponder, text), @@ -243,7 +244,7 @@ void FunctionListController::computeTitlesColumnWidth(bool forceMax) { return; } KDCoordinate maxTitleWidth = maxFunctionNameWidth()+k_functionTitleSumOfMargins; - m_titlesColumnWidth = maxInt(maxTitleWidth, k_minTitleColumnWidth); + m_titlesColumnWidth = std::max(maxTitleWidth, k_minTitleColumnWidth); } TabViewController * FunctionListController::tabController() const { @@ -262,7 +263,7 @@ KDCoordinate FunctionListController::maxFunctionNameWidth() { const char * functionName = record.fullName(); const char * dotPosition = strchr(functionName, Ion::Storage::k_dotChar); assert(dotPosition != nullptr); - maxNameLength = maxInt(maxNameLength, dotPosition-functionName); + maxNameLength = std::max(maxNameLength, static_cast(dotPosition-functionName)); } return nameWidth(maxNameLength + Function::k_parenthesedArgumentCodePointLength); } diff --git a/apps/shared/function_title_cell.cpp b/apps/shared/function_title_cell.cpp index 4a1b11041..c57120bfb 100644 --- a/apps/shared/function_title_cell.cpp +++ b/apps/shared/function_title_cell.cpp @@ -1,11 +1,9 @@ #include "function_title_cell.h" #include +#include namespace Shared { -static inline float minFloat(float x, float y) { return x < y ? x : y; } -static inline float maxFloat(float x, float y) { return x > y ? x : y; } - void FunctionTitleCell::setOrientation(Orientation orientation) { m_orientation = orientation; reloadCell(); @@ -51,9 +49,9 @@ KDRect FunctionTitleCell::subviewFrame() const { float FunctionTitleCell::verticalAlignment() const { assert(m_orientation == Orientation::VerticalIndicator); - return maxFloat( + return std::max( 0.0f, - minFloat( + std::min( 1.0f, m_baseline < 0 ? 0.5f : verticalAlignmentGivenExpressionBaselineAndRowHeight(m_baseline, subviewFrame().height()))); } diff --git a/apps/shared/interactive_curve_view_range.cpp b/apps/shared/interactive_curve_view_range.cpp index 2db5afaa2..dc1c6fd78 100644 --- a/apps/shared/interactive_curve_view_range.cpp +++ b/apps/shared/interactive_curve_view_range.cpp @@ -5,13 +5,12 @@ #include #include #include +#include using namespace Poincare; namespace Shared { -static inline float maxFloat(float x, float y) { return x > y ? x : y; } - uint32_t InteractiveCurveViewRange::rangeChecksum() { float data[5] = {xMin(), xMax(), yMin(), yMax(), m_yAuto ? 1.0f : 0.0f}; size_t dataLengthInBytes = 5*sizeof(float); @@ -94,7 +93,7 @@ void InteractiveCurveViewRange::normalize() { * 1cm = 2 current units. */ m_yAuto = false; - const float unit = maxFloat(xGridUnit(), yGridUnit()); + const float unit = std::max(xGridUnit(), yGridUnit()); // Set x range float newXHalfRange = NormalizedXHalfRange(unit); @@ -160,7 +159,7 @@ void InteractiveCurveViewRange::setDefault() { yRange = yMax() - yMin(); float xyRatio = xRange/yRange; - const float unit = maxFloat(xGridUnit(), yGridUnit()); + const float unit = std::max(xGridUnit(), yGridUnit()); const float newXHalfRange = NormalizedXHalfRange(unit); const float newYHalfRange = NormalizedYHalfRange(unit); float normalizedXYRatio = newXHalfRange/newYHalfRange; diff --git a/apps/shared/range_1D.cpp b/apps/shared/range_1D.cpp index 944118474..320d316c7 100644 --- a/apps/shared/range_1D.cpp +++ b/apps/shared/range_1D.cpp @@ -2,12 +2,10 @@ #include #include #include +#include namespace Shared { -static inline float minFloat(float x, float y) { return x < y ? x : y; } -static inline float maxFloat(float x, float y) { return x > y ? x : y; } - void Range1D::setMin(float min, float lowerMaxFloat, float upperMaxFloat) { min = clipped(min, false, lowerMaxFloat, upperMaxFloat); if (std::isnan(min)) { @@ -43,7 +41,7 @@ float Range1D::defaultRangeLengthFor(float position) { float Range1D::clipped(float x, bool isMax, float lowerMaxFloat, float upperMaxFloat) { float maxF = isMax ? upperMaxFloat : lowerMaxFloat; float minF = isMax ? -lowerMaxFloat : -upperMaxFloat; - return maxFloat(minF, minFloat(x, maxF)); + return std::max(minF, std::min(x, maxF)); } } diff --git a/apps/shared/scrollable_multiple_expressions_view.cpp b/apps/shared/scrollable_multiple_expressions_view.cpp index 12a3fe9c9..8b1d012e3 100644 --- a/apps/shared/scrollable_multiple_expressions_view.cpp +++ b/apps/shared/scrollable_multiple_expressions_view.cpp @@ -1,12 +1,11 @@ #include "scrollable_multiple_expressions_view.h" #include #include +#include using namespace Poincare; namespace Shared { -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } - AbstractScrollableMultipleExpressionsView::ContentCell::ContentCell() : m_rightExpressionView(), m_approximateSign(KDFont::LargeFont, I18n::Message::AlmostEqual, 0.5f, 0.5f, Palette::GreyVeryDark), @@ -75,7 +74,7 @@ KDSize AbstractScrollableMultipleExpressionsView::ContentCell::minimalSizeForOpt centeredExpressionSize = m_centeredExpressionView.minimalSizeForOptimalDisplay(); width += centeredExpressionSize.width() + 2*Metric::CommonLargeMargin + m_approximateSign.minimalSizeForOptimalDisplay().width(); } - KDCoordinate height = maxCoordinate(maxCoordinate(centeredBaseline, rightBaseline), leftViewBaseline) + maxCoordinate(maxCoordinate(centeredExpressionSize.height()-centeredBaseline, rightExpressionSize.height()-rightBaseline), leftSize.height()-leftViewBaseline); + KDCoordinate height = std::max(std::max(centeredBaseline, rightBaseline), leftViewBaseline) + std::max(std::max(centeredExpressionSize.height()-centeredBaseline, rightExpressionSize.height()-rightBaseline), leftSize.height()-leftViewBaseline); return KDSize(width, height); } @@ -134,7 +133,7 @@ void AbstractScrollableMultipleExpressionsView::ContentCell::layoutSubviews(bool KDSize rightExpressionSize = m_rightExpressionView.minimalSizeForOptimalDisplay(); KDCoordinate rightBaseline = m_rightExpressionView.layout().isUninitialized() ? 0 : m_rightExpressionView.layout().baseline(); // Compute baseline - KDCoordinate baseline = maxCoordinate(maxCoordinate(leftViewBaseline, rightBaseline), centeredBaseline); + KDCoordinate baseline = std::max(std::max(leftViewBaseline, rightBaseline), centeredBaseline); // Layout left view KDCoordinate currentWidth = 0; if (leftExpressionView()) { diff --git a/apps/shared/store_controller.cpp b/apps/shared/store_controller.cpp index c52f205c9..ee4244f3b 100644 --- a/apps/shared/store_controller.cpp +++ b/apps/shared/store_controller.cpp @@ -4,11 +4,10 @@ #include "../constant.h" #include #include +#include using namespace Poincare; -static inline int minInt(int x, int y) { return x < y ? x : y; } - namespace Shared { StoreController::ContentView::ContentView(DoublePairStore * store, Responder * parentResponder, TableViewDataSource * dataSource, SelectableTableViewDataSource * selectionDataSource, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate) : @@ -245,7 +244,7 @@ bool StoreController::privateFillColumnWithFormula(Expression formula, Expressio if (numberOfValuesToCompute == -1) { numberOfValuesToCompute = m_store->numberOfPairsOfSeries(series); } else { - numberOfValuesToCompute = minInt(numberOfValuesToCompute, m_store->numberOfPairsOfSeries(series)); + numberOfValuesToCompute = std::min(numberOfValuesToCompute, m_store->numberOfPairsOfSeries(series)); } index++; } diff --git a/apps/shared/text_field_delegate_app.h b/apps/shared/text_field_delegate_app.h index 185646dd6..0dd472e78 100644 --- a/apps/shared/text_field_delegate_app.h +++ b/apps/shared/text_field_delegate_app.h @@ -17,7 +17,7 @@ public: virtual bool XNTCanBeOverriden() const { return true; } virtual CodePoint XNT() { return 'x'; } bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override; - virtual bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override; + bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override; bool isAcceptableText(const char * text); template bool hasUndefinedValue(const char * text, T & value, bool enablePlusInfinity = false, bool enableMinusInfinity = false); diff --git a/apps/shared/values_controller.cpp b/apps/shared/values_controller.cpp index 199c84d4b..6b5262116 100644 --- a/apps/shared/values_controller.cpp +++ b/apps/shared/values_controller.cpp @@ -3,12 +3,15 @@ #include #include #include +#include using namespace Poincare; namespace Shared { -static inline int minInt(int x, int y) { return x < y ? x : y; } +constexpr int ValuesController::k_maxNumberOfDisplayableRows; + +// TODO: use std::abs static inline int absInt(int x) { return x < 0 ? -x : x; } // Constructor and helpers @@ -338,9 +341,9 @@ char * ValuesController::memoizedBufferForCell(int i, int j) { } // Compute the buffer of the new cells of the memoized table int maxI = numberOfValuesColumns() - m_firstMemoizedColumn; - for (int ii = 0; ii < minInt(nbOfMemoizedColumns, maxI); ii++) { + for (int ii = 0; ii < std::min(nbOfMemoizedColumns, maxI); ii++) { int maxJ = numberOfElementsInColumn(absoluteColumnForValuesColumn(ii+m_firstMemoizedColumn)) - m_firstMemoizedRow; - for (int jj = 0; jj < minInt(k_maxNumberOfDisplayableRows, maxJ); jj++) { + for (int jj = 0; jj < std::min(k_maxNumberOfDisplayableRows, maxJ); jj++) { // Escape if already filled if (ii >= -offsetI && ii < -offsetI + nbOfMemoizedColumns && jj >= -offsetJ && jj < -offsetJ + k_maxNumberOfDisplayableRows) { continue; diff --git a/apps/shared/values_controller.h b/apps/shared/values_controller.h index 817de16bc..42d8a2501 100644 --- a/apps/shared/values_controller.h +++ b/apps/shared/values_controller.h @@ -23,13 +23,13 @@ public: TELEMETRY_ID("Values"); // Responder - virtual bool handleEvent(Ion::Events::Event event) override; + bool handleEvent(Ion::Events::Event event) override; void didBecomeFirstResponder() override; void willExitResponderChain(Responder * nextFirstResponder) override; // TableViewDataSource int numberOfColumns() const override; - virtual void willDisplayCellAtLocation(HighlightCell * cell, int i, int j) override; + void willDisplayCellAtLocation(HighlightCell * cell, int i, int j) override; HighlightCell * reusableCell(int index, int type) override; int reusableCellCount(int type) override; int typeAtLocation(int i, int j) override; diff --git a/apps/shared/values_function_parameter_controller.h b/apps/shared/values_function_parameter_controller.h index a39dbed49..f43653123 100644 --- a/apps/shared/values_function_parameter_controller.h +++ b/apps/shared/values_function_parameter_controller.h @@ -20,13 +20,13 @@ public: const char * title() override; void viewWillAppear() override; void didBecomeFirstResponder() override; - virtual int numberOfRows() const override { return 1; } + int numberOfRows() const override { return 1; } KDCoordinate cellHeight() override { return Metric::ParameterCellHeight; } - virtual HighlightCell * reusableCell(int index) override { + HighlightCell * reusableCell(int index) override { assert(index == 0); return &m_copyColumn; } - virtual int reusableCellCount() const override { return 1; } + int reusableCellCount() const override { return 1; } void setRecord(Ion::Storage::Record record) { m_record = record; } protected: MessageTableCellWithChevron m_copyColumn; diff --git a/apps/solver/Makefile b/apps/solver/Makefile index 68c252d9c..d4a9b93db 100644 --- a/apps/solver/Makefile +++ b/apps/solver/Makefile @@ -28,7 +28,8 @@ i18n_files += $(addprefix apps/solver/,\ ) tests_src += $(addprefix apps/solver/test/,\ - equation_store.cpp\ + equation_store.cpp \ + helpers.cpp \ ) $(eval $(call depends_on_image,apps/solver/app.cpp,apps/solver/solver_icon.png)) diff --git a/apps/solver/solutions_controller.cpp b/apps/solver/solutions_controller.cpp index 1afa6220e..22443438b 100644 --- a/apps/solver/solutions_controller.cpp +++ b/apps/solver/solutions_controller.cpp @@ -10,14 +10,13 @@ #include #include #include +#include using namespace Poincare; using namespace Shared; namespace Solver { -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } - constexpr KDColor SolutionsController::ContentView::k_backgroundColor; SolutionsController::ContentView::ContentView(SolutionsController * controller) : @@ -260,7 +259,7 @@ KDCoordinate SolutionsController::rowHeight(int j) { Poincare::Layout approximateLayout = m_equationStore->exactSolutionLayoutAtIndex(j, false); KDCoordinate exactLayoutHeight = exactLayout.layoutSize().height(); KDCoordinate approximateLayoutHeight = approximateLayout.layoutSize().height(); - KDCoordinate layoutHeight = maxCoordinate(exactLayout.baseline(), approximateLayout.baseline()) + maxCoordinate(exactLayoutHeight-exactLayout.baseline(), approximateLayoutHeight-approximateLayout.baseline()); + KDCoordinate layoutHeight = std::max(exactLayout.baseline(), approximateLayout.baseline()) + std::max(exactLayoutHeight-exactLayout.baseline(), approximateLayoutHeight-approximateLayout.baseline()); return layoutHeight + 2 * Metric::CommonSmallMargin; } if (j == rowOfUserVariablesMessage) { diff --git a/apps/solver/solutions_controller.h b/apps/solver/solutions_controller.h index 94327c1ae..8fac34e02 100644 --- a/apps/solver/solutions_controller.h +++ b/apps/solver/solutions_controller.h @@ -23,8 +23,8 @@ public: /* AlternateEmptyViewDefaultDelegate */ bool isEmpty() const override; - virtual I18n::Message emptyMessage() override; - virtual Responder * defaultController() override; + I18n::Message emptyMessage() override; + Responder * defaultController() override; /* TableViewDataSource */ int numberOfRows() const override; int numberOfColumns() const override { return 2; } diff --git a/apps/solver/test/equation_store.cpp b/apps/solver/test/equation_store.cpp index 786d35eeb..11952f66a 100644 --- a/apps/solver/test/equation_store.cpp +++ b/apps/solver/test/equation_store.cpp @@ -1,388 +1,181 @@ #include -#include -#include -#include -#include -#include -#include "../equation_store.h" -#include "../../../poincare/test/helper.h" - -using namespace Poincare; - -namespace Solver { - -void addEquationWithText(EquationStore * equationStore, const char * text, Context * context) { - Ion::Storage::Record::ErrorStatus err = equationStore->addEmptyModel(); - quiz_assert_print_if_failure(err == Ion::Storage::Record::ErrorStatus::None, text); - (void) err; // Silence warning in DEBUG=0 - Ion::Storage::Record record = equationStore->recordAtIndex(equationStore->numberOfModels()-1); - Shared::ExpiringPointer model = equationStore->modelForRecord(record); - model->setContent(text, context); -} - -void assert_equation_system_exact_solve_to(const char * equations[], EquationStore::Error error, EquationStore::Type type, const char * variables[], const char * solutions[], int numberOfSolutions, bool didReplaceFunctionsButNotSymbols = false) { - Shared::GlobalContext globalContext; - EquationStore equationStore; - int index = 0; - while (equations[index] != 0) { - addEquationWithText(&equationStore, equations[index++], &globalContext); - } - bool replaceFunctionsButNotSymbols = false; - EquationStore::Error err = equationStore.exactSolve(&globalContext, &replaceFunctionsButNotSymbols); - quiz_assert_print_if_failure(err == error, equations[0]); - quiz_assert_print_if_failure(replaceFunctionsButNotSymbols == didReplaceFunctionsButNotSymbols, equations[0]); - if (err != EquationStore::Error::NoError) { - equationStore.removeAll(); - return; - } - quiz_assert_print_if_failure(equationStore.type() == type, equations[0]); - quiz_assert_print_if_failure(equationStore.numberOfSolutions() == numberOfSolutions, equations[0]); - if (numberOfSolutions == INT_MAX) { - equationStore.removeAll(); - return; - } - if (type == EquationStore::Type::LinearSystem) { - for (int i = 0; i < numberOfSolutions; i++) { - quiz_assert_print_if_failure(strcmp(equationStore.variableAtIndex(i),variables[i]) == 0, equations[0]); - } - } else { - quiz_assert_print_if_failure(strcmp(equationStore.variableAtIndex(0), variables[0]) == 0, equations[0]); - } - constexpr int bufferSize = 200; - char buffer[bufferSize]; - for (int i = 0; i < numberOfSolutions; i++) { - equationStore.exactSolutionLayoutAtIndex(i, true).serializeForParsing(buffer, bufferSize); - quiz_assert_print_if_failure(strcmp(buffer, solutions[i]) == 0, equations[0]); - } - equationStore.removeAll(); -} - -void assert_equation_approximate_solve_to(const char * equations, double xMin, double xMax, const char * variable, double solutions[], int numberOfSolutions, bool hasMoreSolutions) { - Shared::GlobalContext globalContext; - EquationStore equationStore; - addEquationWithText(&equationStore, equations, &globalContext); - bool replaceFunctionsButNotSymbols = false; - EquationStore::Error err = equationStore.exactSolve(&globalContext, &replaceFunctionsButNotSymbols); - quiz_assert(err == EquationStore::Error::RequireApproximateSolution); - equationStore.setIntervalBound(0, xMin); - equationStore.setIntervalBound(1, xMax); - equationStore.approximateSolve(&globalContext, replaceFunctionsButNotSymbols); - quiz_assert(equationStore.numberOfSolutions() == numberOfSolutions); - quiz_assert(strcmp(equationStore.variableAtIndex(0), variable)== 0); - for (int i = 0; i < numberOfSolutions; i++) { - quiz_assert(std::fabs(equationStore.approximateSolutionAtIndex(i) - solutions[i]) < 1E-5); - } - quiz_assert(equationStore.haveMoreApproximationSolutions(&globalContext, replaceFunctionsButNotSymbols) == hasMoreSolutions); - equationStore.removeAll(); -} +#include "helpers.h" QUIZ_CASE(equation_solve) { - // x+y+z+a+b+c+d = 0 - const char * variables1[] = {""}; - const char * equations0[] = {"x+y+z+a+b+c+d=0", 0}; - assert_equation_system_exact_solve_to(equations0, EquationStore::Error::TooManyVariables, EquationStore::Type::LinearSystem, (const char **)variables1, nullptr, 0); + assert_solves_to_error("x+y+z+a+b+c+d=0", TooManyVariables); + assert_solves_to_error("x^2+y=0", NonLinearSystem); + assert_solves_to_error("cos(x)=0", RequireApproximateSolution); - // x^2+y = 0 - const char * equations1[] = {"x^2+y=0", 0}; - assert_equation_system_exact_solve_to(equations1, EquationStore::Error::NonLinearSystem, EquationStore::Type::LinearSystem, (const char **)variables1, nullptr, 0); + assert_solves_to_no_solution("2=0"); + assert_solves_to_no_solution("x-x+2=0"); - // cos(x) = 0 - const char * equations2[] = {"cos(x)=0", 0}; - assert_equation_system_exact_solve_to(equations2, EquationStore::Error::RequireApproximateSolution, EquationStore::Type::LinearSystem, (const char **)variables1, nullptr, 0); + assert_solves_to_infinite_solutions("0=0"); + assert_solves_to_infinite_solutions("x-x=0"); - // 2 = 0 - const char * equations3[] = {"2=0", 0}; - assert_equation_system_exact_solve_to(equations3, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variables1, nullptr, 0); - // 0 = 0 - const char * equations4[] = {"0=0", 0}; - assert_equation_system_exact_solve_to(equations4, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variables1, nullptr, INT_MAX); + assert_solves_to("2x+3=4", "x=1/2"); + assert_solves_to("3×x^2-4x+4=2", {"x=2/3-(√(2)/3)𝐢", "x=2/3+(√(2)/3)𝐢", "delta=-8"}); + assert_solves_to("2×x^2-4×x+4=3", {"x=(-√(2)+2)/2", "x=(√(2)+2)/2", "delta=8"}); + assert_solves_to("2×x^2-4×x+2=0", {"x=1", "delta=0"}); + assert_solves_to( + "x^2+x+1=3×x^2+π×x-√(5)", + { + "x=(√(π^2-2π+8√(5)+9)-π+1)/4", + "x=(-√(π^2-2π+8×√(5)+9)-π+1)/4", + "delta=π^2-2π+8√(5)+9" + } + ); + assert_solves_to("(x-3)^2=0", {"x=3", "delta=0"}); - // x-x+2 = 0 - const char * equations5[] = {"x-x+2=0", 0}; - assert_equation_system_exact_solve_to(equations5, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variables1, nullptr, 0); - - // x-x= 0 - const char * equations6[] = {"x-x=0", 0}; - assert_equation_system_exact_solve_to(equations6, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variables1, nullptr, INT_MAX); - - const char * variablesx[] = {"x", ""}; - // 2x+3=4 - const char * equations7[] = {"2x+3=4", 0}; - const char * solutions7[] = {"\u0012\u00121\u0013/\u00122\u0013\u0013"}; // 1/2 - assert_equation_system_exact_solve_to(equations7, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesx, solutions7, 1); - - // 3x^2-4x+4=2 - const char * equations8[] = {"3×x^2-4x+4=2", 0}; - const char * solutions8[] = {"\u0012\u00122\u0013/\u00123\u0013\u0013-\u0012\u0012√\u00122\u0013\u0013/\u00123\u0013\u0013𝐢","\u0012\u00122\u0013/\u00123\u0013\u0013+\u0012\u0012√\u00122\u0013\u0013/\u00123\u0013\u0013𝐢", "-8"}; // 2/3-(√(2)/3)𝐢, 2/3+(√(2)/3)𝐢 - assert_equation_system_exact_solve_to(equations8, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, solutions8, 3); - - // 2×x^2-4×x+4=3 - const char * equations9[] = {"2×x^2-4×x+4=3", 0}; - const char * solutions9[] = {"\u0012\u0012-√\u00122\u0013+2\u0013/\u00122\u0013\u0013","\u0012\u0012√\u00122\u0013+2\u0013/\u00122\u0013\u0013", "8"}; // (-√(2)+2)/2, (√(2)+2)/2, 8 - assert_equation_system_exact_solve_to(equations9, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, solutions9, 3); - - // 2×x^2-4×x+2=0 - const char * equations10[] = {"2×x^2-4×x+2=0", 0}; - const char * solutions10[] = {"1", "0"}; - assert_equation_system_exact_solve_to(equations10, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, solutions10, 2); - - // x^2+x+1=3×x^2+pi×x-√(5) - const char * equations11[] = {"x^2+x+1=3×x^2+π×x-√(5)", 0}; - const char * solutions11[] = {"\u0012\u0012√\u0012π^\u00122\u0013-2π+8√\u00125\u0013+9\u0013-π+1\u0013/\u00124\u0013\u0013", "\u0012\u0012-√\u0012π^\u00122\u0013-2π+8√\u00125\u0013+9\u0013-π+1\u0013/\u00124\u0013\u0013", "π^\u00122\u0013-2π+8√\u00125\u0013+9"}; // (√(π^2-2π+8√(5)+9)-π+1)/4, (-√(π^2-2π+8×√(5)+9)-π+1)/4, π^2-2π+8√(5)+9 - assert_equation_system_exact_solve_to(equations11, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, solutions11, 3); - - // (x-3)^2 - const char * equations21[] = {"(x-3)^2=0", 0}; - const char * solutions21[] = {"3", "0"}; - assert_equation_system_exact_solve_to(equations21, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, solutions21, 2); - - // TODO - // x^3 - 4x^2 + 6x - 24 = 0 - //const char * equations10[] = {"2×x^2-4×x+4=3", 0}; - //assert_equation_system_exact_solve_to(equations10, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, {"x", ""}, {"4", "𝐢×√(6)", "-𝐢×√(6)", "-11616"}, 4); - - //x^3+x^2+1=0 - // x^3-3x-2=0 + /* TODO: Cubic + * x^3-4x^2+6x-24=0 + * x^3+x^2+1=0 + * x^3-3x-2=0 */ // Linear System - const char * equations12[] = {"x+y=0", 0}; - assert_equation_system_exact_solve_to(equations12, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesx, nullptr, INT_MAX); - - const char * variablesxy[] = {"x", "y", ""}; - - const char * equations13[] = {"x+y=0", "3x+y=-5", 0}; - const char * solutions13[] = {"-\u0012\u00125\u0013/\u00122\u0013\u0013", "\u0012\u00125\u0013/\u00122\u0013\u0013"}; // -5/2; 5/2 - assert_equation_system_exact_solve_to(equations13, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesxy, solutions13, 2); - - const char * variablesxyz[] = {"x", "y", "z", ""}; - - const char * equations14[] = {"x+y=0", "3x+y+z=-5", "4z-π=0", 0}; - const char * solutions14[] = {"\u0012\u0012-π-20\u0013/\u00128\u0013\u0013", "\u0012\u0012π+20\u0013/\u00128\u0013\u0013", "\u0012\u0012π\u0013/\u00124\u0013\u0013"}; // (-π-20)/8, (π+20)/8, π/4 - assert_equation_system_exact_solve_to(equations14, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesxyz, solutions14, 3); - - const char * variablesxyzabc[] = {"x", "y", "z", "a", "b", "c"}; - const char * equations22[] = {"x+y=0", "3x+y+z=-5", "4z-π=0", "a+b+c=0", "a = 3", "c = a+2", 0}; - const char * solutions22[] = {"\u0012\u0012-π-20\u0013/\u00128\u0013\u0013", "\u0012\u0012π+20\u0013/\u00128\u0013\u0013", "\u0012\u0012π\u0013/\u00124\u0013\u0013", "3", "-8", "5"}; // (-π-20)/8, (π+20)/8, π/4, 3, 5, -8 - assert_equation_system_exact_solve_to(equations22, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesxyzabc, solutions22, 6); + assert_solves_to_infinite_solutions("x+y=0"); + assert_solves_to({"x+y=0", "3x+y=-5"}, {"x=-5/2", "y=5/2"}); + assert_solves_to( + { + "x+y=0", + "3x+y+z=-5", + "4z-π=0" + }, + { + "x=(-π-20)/8", + "y=(π+20)/8", + "z=π/4" + } + ); + assert_solves_to( + { + "x+y=0", + "3x+y+z=-5", + "4z-π=0", + "a+b+c=0", + "a=3", + "c=a+2" + }, + { + "x=(-π-20)/8", + "y=(π+20)/8", + "z=π/4", + "a=3", + "b=-8", + "c=5" + } + ); /* This test case needs the user defined variable. Indeed, in the equation * store, m_variables is just before m_userVariables, so bad fetching in * m_variables might fetch into m_userVariables and create problems. */ - assert_simplify("0→x"); - const char * variablesbDeyzt[] = {"b", "D", "e", "y", "z", "t"}; - const char * equations23[] = {"b=0", "D=0", "e=0", "", "x+y+z+t=0", 0}; - assert_equation_system_exact_solve_to(equations23, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesbDeyzt, nullptr, INT_MAX); - Ion::Storage::sharedStorage()->recordNamed("x.exp").destroy(); + set("x", "0"); + assert_solves_to_infinite_solutions({ + "b=0", + "D=0", + "e=0", + "x+y+z+t=0" + }); + unset("x"); // Monovariable non-polynomial equation - double solutions15[] = {-90.0, 90.0}; - assert_equation_approximate_solve_to("cos(x)=0", -100.0, 100.0, "x", solutions15, 2, false); - - double solutions16[] = {-810.0, -630.0, -450.0, -270.0, -90.0, 90.0, 270.0, 450.0, 630.0, 810.0}; - assert_equation_approximate_solve_to("cos(x)=0", -900.0, 1000.0, "x", solutions16, 10, true); - - double solutions17[] = {0}; - assert_equation_approximate_solve_to("√(y)=0", -900.0, 1000.0, "y", solutions17, 1, false); + assert_solves_numerically_to("cos(x)=0", -100, 100, {-90.0, 90.0}); + assert_solves_numerically_to("cos(x)=0", -900, 1000, {-810.0, -630.0, -450.0, -270.0, -90.0, 90.0, 270.0, 450.0, 630.0, 810.0}); + assert_solves_numerically_to("√(y)=0", -900, 1000, {0}, "y"); // Long variable names - const char * variablesabcde[] = {"abcde", ""}; - const char * equations18[] = {"2abcde+3=4", 0}; - const char * solutions18[] = {"\u0012\u00121\u0013/\u00122\u0013\u0013"}; // 1/2 - assert_equation_system_exact_solve_to(equations18, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesabcde, solutions18, 1); - - const char * variablesBig1Big2[] = {"Big1", "Big2", ""}; - const char * equations19[] = {"Big1+Big2=0", "3Big1+Big2=-5", 0}; - const char * solutions19[] = {"-\u0012\u00125\u0013/\u00122\u0013\u0013", "\u0012\u00125\u0013/\u00122\u0013\u0013"}; // -5/2, 5/2 - assert_equation_system_exact_solve_to(equations19, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesBig1Big2, solutions19, 2); + assert_solves_to("2abcde+3=4", "abcde=1/2"); + assert_solves_to({"Big1+Big2=0", "3Big1+Big2=-5"}, {"Big1=-5/2", "Big2=5/2"}); // conj(x)*x+1 = 0 - const char * equations20one = "conj(x)*x+1=0"; - const char * equations20[] = {equations20one, 0}; - assert_equation_system_exact_solve_to(equations20, EquationStore::Error::RequireApproximateSolution, EquationStore::Type::LinearSystem, (const char **)variables1, nullptr, 0); - assert_equation_approximate_solve_to(equations20one, -100.0, 100.0, "x", nullptr, 0, false); + assert_solves_to_error("conj(x)*x+1=0", RequireApproximateSolution); + assert_solves_numerically_to("conj(x)*x+1=0", -100, 100, {}); } -QUIZ_CASE(equation_solve_complex_format) { - Poincare::Preferences::sharedPreferences()->setComplexFormat(Poincare::Preferences::ComplexFormat::Real); - const char * variablesx[] = {"x", ""}; - // x+I = 0 --> x = -𝐢 - const char * equations0[] = {"x+𝐢=0", 0}; - const char * solutions0[] = {"-𝐢"}; - assert_equation_system_exact_solve_to(equations0, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesx, solutions0, 1); +QUIZ_CASE(equation_solve_complex_real) { + set_complex_format(Real); + assert_solves_to("x+𝐢=0", "x=-𝐢"); // We still want complex solutions if the input has some complex value + assert_solves_to_error("x+√(-1)=0", EquationUnreal); + assert_solves_to("x^2+x+1=0", {"delta=-3"}); + assert_solves_to_error("x^2-√(-1)=0", EquationUnreal); + assert_solves_to_error("x+√(-1)×√(-1)=0", EquationUnreal); + assert_solves_to("root(-8,3)*x+3=0", "x=3/2"); + reset_complex_format(); +} - // x+√(-1) = 0 --> Not defined in R - const char * equations1[] = {"x+√(-1)=0", 0}; - assert_equation_system_exact_solve_to(equations1, EquationStore::Error::EquationUnreal, EquationStore::Type::LinearSystem, (const char **)variablesx, nullptr, 0); +QUIZ_CASE(equation_solve_complex_cartesian) { + set_complex_format(Cartesian); + assert_solves_to("x+𝐢=0", "x=-𝐢"); + assert_solves_to("x+√(-1)=0", "x=-𝐢"); + assert_solves_to({"x^2+x+1=0"}, {"x=-1/2-((√(3))/2)𝐢", "x=-1/2+((√(3))/2)𝐢", "delta=-3"}); + assert_solves_to("x^2-√(-1)=0", {"x=-√(2)/2-(√(2)/2)𝐢", "x=√(2)/2+(√(2)/2)𝐢", "delta=4𝐢"}); + assert_solves_to("x+√(-1)×√(-1)=0", "x=1"); + assert_solves_to("root(-8,3)*x+3=0", "x=-3/4+(3√(3)/4)*𝐢"); + reset_complex_format(); +} - // x^2+x+1=0 --> No solution in R - const char * equations2[] = {"x^2+x+1=0", 0}; - const char * delta2[] = {"-3"}; - assert_equation_system_exact_solve_to(equations2, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, delta2, 1); - - // x^2-√(-1)=0 --> Not defined in R - const char * equations3[] = {"x^2-√(-1)=0", 0}; - assert_equation_system_exact_solve_to(equations3, EquationStore::Error::EquationUnreal, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, nullptr, 0); - - // x+√(-1)×√(-1) = 0 --> Not defined in R - const char * equations4[] = {"x+√(-1)×√(-1)=0", 0}; - assert_equation_system_exact_solve_to(equations4, EquationStore::Error::EquationUnreal, EquationStore::Type::LinearSystem, (const char **)variablesx, nullptr, 0); - - // root(-8,3)*x+3 = 0 --> 3/2 in R - const char * equations5[] = {"root(-8,3)*x+3=0", 0}; - const char * solutions5[] = {"\u0012\u00123\u0013/\u00122\u0013\u0013"}; - assert_equation_system_exact_solve_to(equations5, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesx, solutions5, 1); - - Poincare::Preferences::sharedPreferences()->setComplexFormat(Poincare::Preferences::ComplexFormat::Cartesian); - // x+𝐢 = 0 --> x = -𝐢 - assert_equation_system_exact_solve_to(equations0, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesx, solutions0, 1); - - // x+√(-1) = 0 --> x = -𝐢 - assert_equation_system_exact_solve_to(equations1, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesx, solutions0, 1); - - // x^2+x+1=0 - const char * solutions2[] = {"-\u0012\u00121\u0013/\u00122\u0013\u0013-\u0012\u0012√\u00123\u0013\u0013/\u00122\u0013\u0013𝐢","-\u0012\u00121\u0013/\u00122\u0013\u0013+\u0012\u0012√\u00123\u0013\u0013/\u00122\u0013\u0013𝐢", "-3"}; // -1/2-((√(3))/2)𝐢, -1/2+((√(3))/2)𝐢, -3 - assert_equation_system_exact_solve_to(equations2, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, solutions2, 3); - - // x^2-√(-1)=0 - const char * solutions3[] = {"-\u0012\u0012√\u00122\u0013\u0013/\u00122\u0013\u0013-\u0012\u0012√\u00122\u0013\u0013/\u00122\u0013\u0013𝐢", "\u0012\u0012√\u00122\u0013\u0013/\u00122\u0013\u0013+\u0012\u0012√\u00122\u0013\u0013/\u00122\u0013\u0013𝐢","4𝐢"}; // -√(2)/2-(√(2)/2)𝐢, √(2)/2+(√(2)/2)𝐢, 4𝐢 - assert_equation_system_exact_solve_to(equations3, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, solutions3, 3); - - // x+√(-1)×√(-1) = 0 - const char * solutions4[] = {"1"}; - assert_equation_system_exact_solve_to(equations4, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesx, solutions4, 1); - - const char * solutions5Cartesain[] = {"-\u0012\u00123\u0013/\u00124\u0013\u0013+\u0012\u00123√\u00123\u0013\u0013/\u00124\u0013\u0013𝐢"}; //-3/4+(3√3/4)*𝐢 - assert_equation_system_exact_solve_to(equations5, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesx, solutions5Cartesain, 1); - - Poincare::Preferences::sharedPreferences()->setComplexFormat(Poincare::Preferences::ComplexFormat::Polar); - // x+𝐢 = 0 --> x = e^(-π/2×i) - const char * solutions0Polar[] = {"ℯ^\u0012-\u0012\u0012π\u0013/\u00122\u0013\u0013𝐢\u0013"}; // ℯ^(-(π/2)𝐢) - assert_equation_system_exact_solve_to(equations0, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesx, solutions0Polar, 1); - - // x+√(-1) = 0 --> x = e^(-π/2𝐢) - assert_equation_system_exact_solve_to(equations1, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesx, solutions0Polar, 1); - - // x^2+x+1=0 - const char * solutions2Polar[] = {"ℯ^\u0012-\u0012\u00122π\u0013/\u00123\u0013\u0013𝐢\u0013","ℯ^\u0012\u0012\u00122π\u0013/\u00123\u0013\u0013𝐢\u0013", "3ℯ^\u0012π·𝐢\u0013"}; // ℯ^(-(2π/3)𝐢), ℯ^((2π/3)𝐢), 3ℯ^(π𝐢) - assert_equation_system_exact_solve_to(equations2, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, solutions2Polar, 3); - - // x^2-√(-1)=0 - const char * solutions3Polar[] = {"ℯ^\u0012-\u0012\u00123π\u0013/\u00124\u0013\u0013𝐢\u0013", "ℯ^\u0012\u0012\u0012π\u0013/\u00124\u0013\u0013𝐢\u0013", "4ℯ^\u0012\u0012\u0012π\u0013/\u00122\u0013\u0013𝐢\u0013"}; // ℯ^(-(3×π/4)𝐢)"‰, "ℯ^((π/4)𝐢)", "4ℯ^((π/2)𝐢) - assert_equation_system_exact_solve_to(equations3, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, solutions3Polar, 3); - - const char * solutions5Polar[] = {"\u0012\u00123\u0013/\u00122\u0013\u0013ℯ^\u0012\u0012\u00122π\u0013/\u00123\u0013\u0013𝐢\u0013"}; //3/2ℯ^\u0012\u00122π\u0012/3\u0013𝐢"}; - assert_equation_system_exact_solve_to(equations5, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesx, solutions5Polar, 1); - - // Put back the complex format - Poincare::Preferences::sharedPreferences()->setComplexFormat(Poincare::Preferences::ComplexFormat::Real); +QUIZ_CASE(equation_solve_complex_polar) { + set_complex_format(Polar); + assert_solves_to("x+𝐢=0", "x=ℯ^(-(π/2)𝐢)"); + assert_solves_to("x+√(-1)=0", "x=ℯ^(-(π/2)𝐢)"); + assert_solves_to("x^2+x+1=0", {"x=ℯ^(-(2π/3)𝐢)", "x=ℯ^((2π/3)𝐢)", "delta=3ℯ^(π𝐢)"}); + assert_solves_to("x^2-√(-1)=0", {"x=ℯ^(-(3π/4)𝐢)", "x=ℯ^((π/4)𝐢)", "delta=4ℯ^((π/2)𝐢)"}); + assert_solves_to("root(-8,3)*x+3=0", "x=3/2×ℯ^((2π/3)𝐢)"); + reset_complex_format(); } QUIZ_CASE(equation_and_symbolic_computation) { - // x+a=0 : non linear system - const char * equation1[] = {"x+a=0", 0}; - assert_equation_system_exact_solve_to(equation1, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, nullptr, nullptr, INT_MAX); + assert_solves_to_infinite_solutions("x+a=0"); - // -3->a - Shared::GlobalContext globalContext; - Expression::ParseAndSimplify("-3→a", &globalContext, Preferences::ComplexFormat::Polar, Preferences::AngleUnit::Degree); + set("a", "-3"); + assert_solves_to("x+a=0", "x=3"); - // x+a = 0 : x = 3 - const char * variables1[] = {"x", ""}; - const char * solutions1[] = {"3"}; - assert_equation_system_exact_solve_to(equation1, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variables1, solutions1, 1); + assert_solves_to("a=0", "a=0"); + /* The equation has no solution since the user defined a = -3. So a is not + * replaced with its context value, and the solution is a = 0. */ - /* a = 0 : the equation has no solution as the user defined a = -3, so a is - * not replaced with its context value and the result is a = 0. */ - const char * equation2[] = {"a=0", 0}; - const char * variables2[] = {"a", ""}; - const char * solutions2[] = {"0"}; - assert_equation_system_exact_solve_to(equation2, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variables2, solutions2, 1, true); + set("b", "-4"); + assert_solves_to_infinite_solutions("a+b=0"); + /* The equation has no solution since the user defined a = -3 and b = -4. + * So neither a nor b are replaced with their context values. Therefore the + * solution is an infinity of solutions. */ - // 4->b - Expression::ParseAndSimplify("-4→b", &globalContext, Preferences::ComplexFormat::Polar, Preferences::AngleUnit::Degree); + assert_solves_to("a+b+c=0", "c=7"); - /* a + b = 0 : the equation has no solution as the user defined a = -3, and - * b = -4 so a and b are not replaced with their context values and the result - * is an infinity of solutions. */ - const char * equation3[] = {"a+b=0", 0}; - const char * variables3[] = {"a", "b", ""}; - assert_equation_system_exact_solve_to(equation3, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variables3, nullptr, INT_MAX, true); + assert_solves_to({"a+c=0", "a=3"}, {"a=3", "c=-3"}); + /* The system has no solution since the user defined a = -3. So a is not + * replaced with its context value, and the solution is a = 3 and c = -3. */ - // a + b + c = 0 : the equation has the solution c = -7 - const char * equation4[] = {"a+b+c=0", 0}; - const char * variables4[] = {"c", ""}; - const char * solutions4[] = {"7"}; - assert_equation_system_exact_solve_to(equation4, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variables4, solutions4, 1); + set("f(x)", "x+1"); - /* a + c = 0 and a = 3: the system has no solution as the user defined a = -3, - * so a is not replaced with its context value and the result is a = 3 and - * c = -3. */ - const char * equation5[] = {"a+c=0", "a=3", 0}; - const char * variables5[] = {"a", "c", ""}; - const char * solutions5[] = {"3", "-3"}; - assert_equation_system_exact_solve_to(equation5, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variables5, solutions5, 2, true); + assert_solves_to("f(x)=0", "x=-1"); - // x+1->f(x) - Expression::ParseAndSimplify("x+1→f(x)", &globalContext, Preferences::ComplexFormat::Polar, Preferences::AngleUnit::Degree); + assert_solves_to("f(a)=0", "a=-1"); + /* The equation has no solution since the user defined a = -3. So a is not + * replaced with its context value, and the solution is a = -1. */ - // f(x) = 0 : x = -1 - const char * equation6[] = {"f(x)=0", 0}; - const char * variables6[] = {"x", ""}; - const char * solutions6[] = {"-1",}; - assert_equation_system_exact_solve_to(equation6, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variables6, solutions6, 1); + set("g(x)", "a+x+2"); - /* f(a) = 0 : the equation has no solution as the user defined a = -3, so a is - * not replaced with its context value and the result is a = -1. */ - const char * equation7[] = {"f(a)=0", 0}; - const char * variables7[] = {"a", ""}; - const char * solutions7[] = {"-1",}; - assert_equation_system_exact_solve_to(equation7, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variables7, solutions7, 1, true); + assert_solves_to("g(x)=0", "x=1"); - // a+x+1->g(x) - Expression::ParseAndSimplify("a+x+2→g(x)", &globalContext, Preferences::ComplexFormat::Polar, Preferences::AngleUnit::Degree); + assert_solves_to("g(a)=0", "a=-1"); + /* The equation has no solution since the user defined a = -3. So a is not + * replaced with its context value, and the equation becomes a + a + 2 = 0. + * The solution is therefore a = -1. */ - // g(x) = 0 : x = 2 - const char * equation8[] = {"g(x)=0", 0}; - const char * variables8[] = {"x", ""}; - const char * solutions8[] = {"1",}; - assert_equation_system_exact_solve_to(equation8, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variables8, solutions8, 1); + set("d", "5"); + set("c", "d"); + set("h(x)", "c+d+3"); + assert_solves_to({"h(x)=0", "c=-3"}, {"c=-3", "d=0"}); + // c and d context values should not be used - /* g(a) = 0 : the equation has no solution as the user defined a = -3, so a is - * not replaced with its context value and the equation becomes a+a+2=0. The - * solution is a = -1. */ - const char * equation9[] = {"g(a)=0", 0}; - const char * variables9[] = {"a", ""}; - const char * solutions9[] = {"-1",}; - assert_equation_system_exact_solve_to(equation9, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variables9, solutions9, 1, true); - - /* c = d - * d = 5 - * h(x) = c + d + 3 - * /c = -3 - * \h(x) = 0 - * c and d context values should not be used, and the solution is c = -3, d = 0 */ - Expression::ParseAndSimplify("5→d", &globalContext, Preferences::ComplexFormat::Polar, Preferences::AngleUnit::Degree); - Expression::ParseAndSimplify("d→c", &globalContext, Preferences::ComplexFormat::Polar, Preferences::AngleUnit::Degree); - Expression::ParseAndSimplify("c+d+3→h(x)", &globalContext, Preferences::ComplexFormat::Polar, Preferences::AngleUnit::Degree); - const char * equation10[] = {"h(x)=0", "c = -3", 0}; - const char * variables10[] = {"c", "d", ""}; - const char * solutions10[] = {"-3", "0"}; - assert_equation_system_exact_solve_to(equation10, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variables10, solutions10, 2, true); - - const char * equation11[] = {"c+d=5", "c-d=1", 0}; - const char * variables11[] = {"c", "d", ""}; - const char * solutions11[] = {"3", "2"}; - assert_equation_system_exact_solve_to(equation11, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variables11, solutions11, 2, true); - - - // Clean the storage - Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); - Ion::Storage::sharedStorage()->recordNamed("b.exp").destroy(); - Ion::Storage::sharedStorage()->recordNamed("c.exp").destroy(); - Ion::Storage::sharedStorage()->recordNamed("d.exp").destroy(); - Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); - Ion::Storage::sharedStorage()->recordNamed("g.func").destroy(); - Ion::Storage::sharedStorage()->recordNamed("h.func").destroy(); -} + assert_solves_to({"c+d=5", "c-d=1"}, {"c=3", "d=2"}); + unset("a"); + unset("b"); + unset("c"); + unset("d"); + unset("e"); + unset("f"); + unset("g"); + unset("h"); } diff --git a/apps/solver/test/helpers.cpp b/apps/solver/test/helpers.cpp new file mode 100644 index 000000000..119e085f6 --- /dev/null +++ b/apps/solver/test/helpers.cpp @@ -0,0 +1,158 @@ +#include +#include +#include +#include +#include +#include +#include "../equation_store.h" + +#include "helpers.h" + +using namespace Solver; +using namespace Poincare; + +// Private sub-helpers + +template +void solve_and_process_error(std::initializer_list equations, T && lambda) { + Shared::GlobalContext globalContext; + EquationStore equationStore; + for (const char * equation : equations) { + Ion::Storage::Record::ErrorStatus err = equationStore.addEmptyModel(); + quiz_assert_print_if_failure(err == Ion::Storage::Record::ErrorStatus::None, equation); + Ion::Storage::Record record = equationStore.recordAtIndex(equationStore.numberOfModels()-1); + Shared::ExpiringPointer model = equationStore.modelForRecord(record); + model->setContent(equation, &globalContext); + } + bool replaceFunctionsButNotSymbols = false; + EquationStore::Error err = equationStore.exactSolve(&globalContext, &replaceFunctionsButNotSymbols); + lambda(&equationStore, err); + equationStore.removeAll(); +} + +template +void solve_and(std::initializer_list equations, T && lambda) { + solve_and_process_error(equations, [lambda](EquationStore * store, EquationStore::Error error) { + quiz_assert(error == NoError); + lambda(store); + }); +} + + +// Helpers + +void assert_solves_to_error(const char * equation, EquationStore::Error error) { + solve_and_process_error({equation},[error](EquationStore * store, EquationStore::Error e){ + quiz_assert(e == error); + }); +} + +void assert_solves_to_infinite_solutions(std::initializer_list equations) { + solve_and(equations, [](EquationStore * store){ + quiz_assert(store->numberOfSolutions() == INT_MAX); + }); +} + +void assert_solves_to(std::initializer_list equations, std::initializer_list solutions) { + solve_and(equations, [solutions](EquationStore * store){ + Shared::GlobalContext globalContext; + int i = 0; + for (const char * solution : solutions) { + // Solutions are specified under the form "foo=bar" + constexpr int maxSolutionLength = 100; + char editableSolution[maxSolutionLength]; + strlcpy(editableSolution, solution, maxSolutionLength); + + char * equal = strchr(editableSolution, '='); + quiz_assert(equal != nullptr); + *equal = 0; + + const char * expectedVariable = editableSolution; + if (store->type() != EquationStore::Type::PolynomialMonovariable) { + /* For some reason the EquationStore returns up to 3 results but always + * just one variable, so we don't check variable name... + * TODO: Change this poor behavior. */ + const char * obtainedVariable = store->variableAtIndex(i); + quiz_assert(strcmp(obtainedVariable, expectedVariable) == 0); + } + + /* Now for the ugly part! + * At the moment, the EquationStore doesn't let us retrieve solutions as + * Expression. We can only get Layout. It somewhat makes sense for how it + * is used in the app, but it's a nightmare to test, so changing this + * behavior is a TODO. */ + + const char * expectedValue = equal + 1; + + /* We compare Expressions, by parsing the expected Expression and + * serializing and parsing the obtained layout. We need to ignore the + * parentheses during the comparison, because to create an expression from + * a const char * we need to add parentheses that are not necessary when + * creating an expression from a layout. */ + + Expression expectedExpression = Expression::Parse(expectedValue, &globalContext, false); + quiz_assert(!expectedExpression.isUninitialized()); + + Layout obtainedLayout = store->exactSolutionLayoutAtIndex(i, true); + constexpr int bufferSize = 200; + char obtainedLayoutBuffer[bufferSize]; + obtainedLayout.serializeForParsing(obtainedLayoutBuffer, bufferSize); + Expression obtainedExpression = Expression::Parse(obtainedLayoutBuffer, &globalContext, false); + quiz_assert(expectedExpression.isIdenticalToWithoutParentheses(obtainedExpression)); + + i++; + } + quiz_assert(store->numberOfSolutions() == i); + }); +} + +void assert_solves_numerically_to(const char * equation, double min, double max, std::initializer_list solutions, const char * variable) { + solve_and_process_error({equation},[min,max,solutions,variable](EquationStore * store, EquationStore::Error e){ + Shared::GlobalContext globalContext; + quiz_assert(e == RequireApproximateSolution); + store->setIntervalBound(0, min); + store->setIntervalBound(1, max); + store->approximateSolve(&globalContext, false); + + quiz_assert(strcmp(store->variableAtIndex(0), variable)== 0); + int i = 0; + for (double solution : solutions) { + quiz_assert(std::fabs(store->approximateSolutionAtIndex(i++) - solution) < 1E-5); + } + quiz_assert(store->numberOfSolutions() == i); + }); +} + +void set_complex_format(Preferences::ComplexFormat format) { + Preferences::sharedPreferences()->setComplexFormat(format); +} +void reset_complex_format() { + Preferences defaultPreferences; + Preferences::sharedPreferences()->setComplexFormat(defaultPreferences.complexFormat()); +} + +void set(const char * variable, const char * value) { + const char * assign = "→"; + + char buffer[32]; + assert(strlen(value) + strlen(assign) + strlen(variable) < sizeof(buffer)); + + buffer[0] = 0; + strlcat(buffer, value, sizeof(buffer)); + strlcat(buffer, assign, sizeof(buffer)); + strlcat(buffer, variable, sizeof(buffer)); + + Shared::GlobalContext globalContext; + Expression::ParseAndSimplify( + buffer, + &globalContext, + Preferences::sharedPreferences()->complexFormat(), + Preferences::sharedPreferences()->angleUnit() + ); +} + +void unset(const char * variable) { + // The variable is either an expression or a function + Ion::Storage::sharedStorage()->destroyRecordWithBaseNameAndExtension(variable, "exp"); + Ion::Storage::sharedStorage()->destroyRecordWithBaseNameAndExtension(variable, "func"); +} diff --git a/apps/solver/test/helpers.h b/apps/solver/test/helpers.h new file mode 100644 index 000000000..5b939c47b --- /dev/null +++ b/apps/solver/test/helpers.h @@ -0,0 +1,49 @@ +#ifndef APPS_SOLVER_TEST_HELPERS_H +#define APPS_SOLVER_TEST_HELPERS_H + +#include +#include +#include "../equation_store.h" +#include + +#define bring_in(prefix, value) static const prefix value = prefix::value; + +bring_in(Solver::EquationStore::Error, EquationUnreal); +bring_in(Solver::EquationStore::Error, NoError); +bring_in(Solver::EquationStore::Error, NonLinearSystem); +bring_in(Solver::EquationStore::Error, RequireApproximateSolution); +bring_in(Solver::EquationStore::Error, TooManyVariables); + +// Custom assertions + +void assert_solves_to(std::initializer_list equations, std::initializer_list solutions); +void assert_solves_numerically_to(const char * equation, double min, double max, std::initializer_list solutions, const char * variable = "x"); +void assert_solves_to_error(const char * equation, Solver::EquationStore::Error error); +void assert_solves_to_infinite_solutions(std::initializer_list equations); + +// Shorthands +inline void assert_solves_to_no_solution(const char * equation) { + /* Note: Doesn't really work with quadratic equations that will always report + * at least a delta value. */ + assert_solves_to({equation}, {}); +} +inline void assert_solves_to_infinite_solutions(const char * equation) { + assert_solves_to_infinite_solutions({equation}); +} +inline void assert_solves_to(const char * equation, const char * solution) { + assert_solves_to({equation}, {solution}); +} +inline void assert_solves_to(const char * equation, std::initializer_list solutions) { + assert_solves_to({equation}, solutions); +} + + +// Helpers + +void set_complex_format(Poincare::Preferences::ComplexFormat format); +void reset_complex_format(); + +void set(const char * variable, const char * value); +void unset(const char * variable); + +#endif diff --git a/apps/statistics/histogram_controller.cpp b/apps/statistics/histogram_controller.cpp index a3ad6decd..42d5c52a3 100644 --- a/apps/statistics/histogram_controller.cpp +++ b/apps/statistics/histogram_controller.cpp @@ -4,6 +4,7 @@ #include "app.h" #include #include +#include #include #include #include @@ -13,9 +14,6 @@ using namespace Shared; namespace Statistics { -static inline float minFloat(float x, float y) { return x < y ? x : y; } -static inline float maxFloat(float x, float y) { return x > y ? x : y; } - HistogramController::HistogramController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, ButtonRowController * header, Store * store, uint32_t * storeVersion, uint32_t * barVersion, uint32_t * rangeVersion, int * selectedBarIndex, int * selectedSeriesIndex) : MultipleDataViewController(parentResponder, store, selectedBarIndex, selectedSeriesIndex), ButtonRowDelegate(header, nullptr), @@ -193,8 +191,8 @@ void HistogramController::preinitXRangeParameters() { float maxValue = -FLT_MAX; for (int i = 0; i < Store::k_numberOfSeries; i ++) { if (!m_store->seriesIsEmpty(i)) { - minValue = minFloat(minValue, m_store->minValue(i)); - maxValue = maxFloat(maxValue, m_store->maxValue(i)); + minValue = std::min(minValue, m_store->minValue(i)); + maxValue = std::max(maxValue, m_store->maxValue(i)); } } m_store->setXMin(minValue); diff --git a/apps/toolbox.fr.i18n b/apps/toolbox.fr.i18n index bb9978e74..85e1ba27c 100644 --- a/apps/toolbox.fr.i18n +++ b/apps/toolbox.fr.i18n @@ -20,7 +20,7 @@ UnitDistanceMeterMicro = "Micromètre" UnitDistanceMeterNano = "Nanomètre" UnitDistanceMeterPico = "Picomètre" UnitDistanceAstronomicalUnit = "Unité astronomique" -UnitDistanceLightYear = "Année lumière" +UnitDistanceLightYear = "Année-lumière" UnitDistanceParsec = "Parsec" UnitMassMenu = "Masse" UnitMassGramKilo = "Kilogramme" @@ -103,7 +103,7 @@ UnitVolumeLiterMilli = "Millilitre" Toolbox = "Boîte à outils" AbsoluteValue = "Valeur absolue" NthRoot = "Racine n-ième" -BasedLogarithm = "Logarithme base a" +BasedLogarithm = "Logarithme de base a" Calculation = "Calcul" ComplexNumber = "Nombres complexes" Combinatorics = "Dénombrement" @@ -114,8 +114,8 @@ Identity = "Matrice identité de taille n" Lists = "Listes" HyperbolicTrigonometry = "Trigonométrie hyperbolique" Fluctuation = "Intervalle de fluctuation" -DerivateNumber = "Nombre derivé" -Integral = "Intégrale" +DerivateNumber = "Nombre derivé de f en a" +Integral = "Intégrale de f sur [a;b]" Sum = "Somme" Product = "Produit" ComplexAbsoluteValue = "Module" @@ -125,22 +125,22 @@ ImaginaryPart = "Partie imaginaire" Conjugate = "Conjugué" Combination = "k parmi n" Permutation = "Arrangement" -GreatCommonDivisor = "PGCD" -LeastCommonMultiple = "PPCM" +GreatCommonDivisor = "PGCD de p et q" +LeastCommonMultiple = "PPCM de p et q" Remainder = "Reste de la division de p par q" Quotient = "Quotient de la division de p par q" -Inverse = "Inverse" -Determinant = "Déterminant" -Transpose = "Transposée" -Trace = "Trace" -Dimension = "Taille" +Inverse = "Inverse de M" +Determinant = "Déterminant de M" +Transpose = "Transposée de M" +Trace = "Trace de M" +Dimension = "Taille de M" Sort = "Tri croissant" InvSort = "Tri décroissant" Maximum = "Maximum" Minimum = "Minimum" -Floor = "Partie entière" -FracPart = "Partie fractionnaire" -Ceiling = "Plafond" +Floor = "Partie entière par défaut" +FracPart = "Partie décimale" +Ceiling = "Partie entière par excès" Rounding = "Arrondi à n décimales" HyperbolicCosine = "Cosinus hyperbolique" HyperbolicSine = "Sinus hyperbolique" @@ -152,8 +152,8 @@ Prediction95 = "Intervalle fluctuation 95% (Term)" Prediction = "Intervalle fluctuation simple (2de)" Confidence = "Intervalle de confiance" RandomAndApproximation = "Aléatoire et approximation" -RandomFloat = "Nombre décimal dans [0,1[" -RandomInteger = "Entier aléatoire dans [a,b]" +RandomFloat = "Nombre décimal dans [0;1[" +RandomInteger = "Entier aléatoire dans [a;b]" PrimeFactorDecomposition = "Décomposition en facteurs premiers" NormCDF = "P(X #include #include +#include using namespace Poincare; using namespace Shared; using namespace Ion; -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } -static inline KDCoordinate maxInt(int x, int y) { return x > y ? x : y; } - VariableBoxController::VariableBoxController() : NestedMenuController(nullptr, I18n::Message::Variables), m_currentPage(Page::RootMenu), @@ -129,7 +127,7 @@ KDCoordinate VariableBoxController::rowHeight(int index) { if (m_currentPage != Page::RootMenu) { Layout layoutR = expressionLayoutForRecord(recordAtIndex(index), index); if (!layoutR.isUninitialized()) { - return maxCoordinate(layoutR.layoutSize().height()+k_leafMargin, Metric::ToolboxRowHeight); + return std::max(layoutR.layoutSize().height()+k_leafMargin, Metric::ToolboxRowHeight); } } return NestedMenuController::rowHeight(index); @@ -289,7 +287,7 @@ void VariableBoxController::destroyRecordAtRowIndex(int rowIndex) { // The deleted row is after the memoization return; } - for (int i = maxInt(0, rowIndex - m_firstMemoizedLayoutIndex); i < k_maxNumberOfDisplayedRows - 1; i++) { + for (int i = std::max(0, rowIndex - m_firstMemoizedLayoutIndex); i < k_maxNumberOfDisplayedRows - 1; i++) { m_layouts[i] = m_layouts[i+1]; } m_layouts[k_maxNumberOfDisplayedRows - 1] = Layout(); diff --git a/build/defaults.mak b/build/defaults.mak index e9814d91e..1b3380249 100644 --- a/build/defaults.mak +++ b/build/defaults.mak @@ -2,7 +2,6 @@ HOSTCC = gcc HOSTCXX = g++ PYTHON = python3 -SFLAGS += -DDEBUG=$(DEBUG) SFLAGS += -DLEDS_CHOICE=$(LEDS_CHOICE) ifdef USERNAME SFLAGS += -DUSERNAME="$(USERNAME)" @@ -17,9 +16,15 @@ CXXFLAGS = -std=c++11 -fno-exceptions -fno-rtti -fno-threadsafe-statics # Flags - Optimizations ifeq ($(DEBUG),1) -SFLAGS = -O0 -g +SFLAGS += -O0 -g else -SFLAGS = -Os +SFLAGS += -Os +SFLAGS += -DNDEBUG +endif + +ifeq ($(ASAN),1) +SFLAGS += -fsanitize=address +LDFLAGS += -fsanitize=address endif # Flags - Header search path diff --git a/build/metrics/binary_size.py b/build/metrics/binary_size.py index c9c07937c..867661070 100644 --- a/build/metrics/binary_size.py +++ b/build/metrics/binary_size.py @@ -8,8 +8,8 @@ import urllib.parse # ELF analysis -def loadable_sections(elf_file, address_prefix = ""): - objdump_section_headers_pattern = re.compile("^\s+\d+\s+(\.[\w\.]+)\s+([0-9a-f]+)\s+([0-9a-f]+)\s+("+address_prefix+"[0-9a-f]+)\s+([0-9a-f]+).*LOAD", flags=re.MULTILINE) +def loadable_sections(elf_file): + objdump_section_headers_pattern = re.compile("^\s+\d+\s+(\.[\w\.]+)\s+([0-9a-f]+)\s+([0-9a-f]+)\s+([0-9a-f]+)\s+([0-9a-f]+)", flags=re.MULTILINE) objdump_output = subprocess.check_output(["arm-none-eabi-objdump", "-h", "-w", elf_file]).decode('utf-8') sections = [] for (name, size, vma, lma, offset) in re.findall(objdump_section_headers_pattern, objdump_output): @@ -21,19 +21,16 @@ def loadable_sections(elf_file, address_prefix = ""): # Data filtering -def biggest_sections(sections, n): - sorted_sections = sorted(sections, key=lambda s: s['size'], reverse=True) - return sorted_sections[:n] - -def total_size(sections): - return sum(map(lambda s: s['size'], sections)) - -def row_for_elf(elf, columns): +def row_for_elf(elf, requested_section_prefixes): sections = loadable_sections(elf) result = {} - for s in biggest_sections(sections, columns): - result[s['name']] = s['size'] - result['Total'] = total_size(sections) + for prefix in requested_section_prefixes: + for s in sections: + section_name = s['name'] + if s['name'].startswith(prefix): + if not prefix in result: + result[prefix] = 0 + result[prefix] += s['size'] return result @@ -119,7 +116,7 @@ def format_table(table): parser = argparse.ArgumentParser(description='Compute binary size metrics') parser.add_argument('files', type=str, nargs='+', help='an ELF file') parser.add_argument('--labels', type=str, nargs='+', help='label for ELF file') -parser.add_argument('--number-of-sections', type=int, default=2, help='Number of detailed sections') +parser.add_argument('--sections', type=str, nargs='+', help='Section (prefix) to list') parser.add_argument('--escape', action='store_true', help='Escape the output') args = parser.parse_args() @@ -131,7 +128,7 @@ for i,filename in enumerate(args.files): label = os.path.basename(filename) if args.labels and i < len(args.labels): label = args.labels[i] - table.append({'label': label, 'values': row_for_elf(filename, args.number_of_sections)}) + table.append({'label': label, 'values': row_for_elf(filename, args.sections)}) formatted_table = format_table(table) if args.escape: diff --git a/build/platform.blackbox.mak b/build/platform.blackbox.mak index 244c172ad..235feb87a 100644 --- a/build/platform.blackbox.mak +++ b/build/platform.blackbox.mak @@ -1,9 +1,4 @@ TOOLCHAIN ?= host-gcc USE_LIBA ?= 0 ION_KEYBOARD_LAYOUT = layout_B2 -EXE = bin - -ifeq ($(DEBUG),1) -else -SFLAGS += -DNDEBUG -endif +EXE = bin \ No newline at end of file diff --git a/build/platform.simulator.mak b/build/platform.simulator.mak index c6a904e30..e25beb0b8 100644 --- a/build/platform.simulator.mak +++ b/build/platform.simulator.mak @@ -17,4 +17,4 @@ SFLAGS += -DEPSILON_SIMULATOR_HAS_LIBPNG=$(EPSILON_SIMULATOR_HAS_LIBPNG) ifeq ($(EPSILON_SIMULATOR_HAS_LIBPNG),1) SFLAGS += `libpng-config --cflags` LDFLAGS += `libpng-config --ldflags` -endif +endif \ No newline at end of file diff --git a/build/toolchain.afl.mak b/build/toolchain.afl.mak index a3e56d9be..28fa52426 100644 --- a/build/toolchain.afl.mak +++ b/build/toolchain.afl.mak @@ -2,3 +2,7 @@ export AFL_QUIET = 1 CC = afl-clang CXX = afl-clang++ LD = afl-clang++ + +ifeq ($(ASAN),1) +export AFL_USE_ASAN = 1 +endif diff --git a/escher/Makefile b/escher/Makefile index 343a49eaf..158cdedaa 100644 --- a/escher/Makefile +++ b/escher/Makefile @@ -53,6 +53,7 @@ escher_src += $(addprefix escher/src/,\ message_table_cell_with_message.cpp \ message_table_cell_with_switch.cpp \ message_text_view.cpp \ + metric.cpp \ modal_view_controller.cpp \ nested_menu_controller.cpp \ palette.cpp \ diff --git a/escher/include/escher/even_odd_editable_text_cell.h b/escher/include/escher/even_odd_editable_text_cell.h index b462144c6..c9986766e 100644 --- a/escher/include/escher/even_odd_editable_text_cell.h +++ b/escher/include/escher/even_odd_editable_text_cell.h @@ -11,7 +11,7 @@ public: EditableTextCell * editableTextCell(); void setEven(bool even) override; void setHighlighted(bool highlight) override; - virtual Responder * responder() override { + Responder * responder() override { return this; } const char * text() const override { diff --git a/escher/include/escher/message_table_cell.h b/escher/include/escher/message_table_cell.h index 788bfb1b1..10a0e795b 100644 --- a/escher/include/escher/message_table_cell.h +++ b/escher/include/escher/message_table_cell.h @@ -9,7 +9,7 @@ class MessageTableCell : public TableCell { public: MessageTableCell(I18n::Message label = (I18n::Message)0, const KDFont * font = KDFont::SmallFont, Layout layout = Layout::HorizontalLeftOverlap); View * labelView() const override; - virtual void setHighlighted(bool highlight) override; + void setHighlighted(bool highlight) override; void setMessage(I18n::Message message); virtual void setTextColor(KDColor color); void setMessageFont(const KDFont * font); diff --git a/escher/include/escher/nested_menu_controller.h b/escher/include/escher/nested_menu_controller.h index 0ff69acfe..0037d9c90 100644 --- a/escher/include/escher/nested_menu_controller.h +++ b/escher/include/escher/nested_menu_controller.h @@ -19,7 +19,7 @@ public: void viewDidDisappear() override; //ListViewDataSource - virtual KDCoordinate rowHeight(int j) override; + KDCoordinate rowHeight(int j) override; HighlightCell * reusableCell(int index, int type) override; protected: class Stack { diff --git a/escher/include/escher/scroll_view.h b/escher/include/escher/scroll_view.h index a5790af32..34225273e 100644 --- a/escher/include/escher/scroll_view.h +++ b/escher/include/escher/scroll_view.h @@ -106,8 +106,8 @@ protected: void layoutSubviews(bool force = false) override; virtual KDSize contentSize() const { return m_contentView->minimalSizeForOptimalDisplay(); } #if ESCHER_VIEW_LOGGING - virtual const char * className() const override; - virtual void logAttributes(std::ostream &os) const override; + const char * className() const override; + void logAttributes(std::ostream &os) const override; #endif View * m_contentView; private: diff --git a/escher/include/escher/scroll_view_indicator.h b/escher/include/escher/scroll_view_indicator.h index 6779b7fd9..4b81198bd 100644 --- a/escher/include/escher/scroll_view_indicator.h +++ b/escher/include/escher/scroll_view_indicator.h @@ -10,8 +10,8 @@ public: KDCoordinate margin() const { return m_margin; } protected: #if ESCHER_VIEW_LOGGING - virtual const char * className() const override; - virtual void logAttributes(std::ostream &os) const override; + const char * className() const override; + void logAttributes(std::ostream &os) const override; #endif KDColor m_color; KDCoordinate m_margin; diff --git a/escher/include/escher/selectable_table_view.h b/escher/include/escher/selectable_table_view.h index f10a606be..6e4fb7ac0 100644 --- a/escher/include/escher/selectable_table_view.h +++ b/escher/include/escher/selectable_table_view.h @@ -25,9 +25,9 @@ public: void selectRow(int j); void selectColumn(int i); void reloadData(bool setFirstResponder = true); - virtual bool handleEvent(Ion::Events::Event event) override; - virtual void didEnterResponderChain(Responder * previousFirstResponder) override; - virtual void willExitResponderChain(Responder * nextFirstResponder) override; + bool handleEvent(Ion::Events::Event event) override; + void didEnterResponderChain(Responder * previousFirstResponder) override; + void willExitResponderChain(Responder * nextFirstResponder) override; void deselectTable(bool withinTemporarySelection = false); bool selectCellAtLocation(int i, int j, bool setFirstResponder = true, bool withinTemporarySelection = false); HighlightCell * selectedCell(); diff --git a/escher/include/escher/toolbox.h b/escher/include/escher/toolbox.h index da8e5d4f6..e38df51ed 100644 --- a/escher/include/escher/toolbox.h +++ b/escher/include/escher/toolbox.h @@ -18,15 +18,15 @@ public: int reusableCellCount(int type) override; void willDisplayCellForIndex(HighlightCell * cell, int index) override; int typeAtLocation(int i, int j) override; - virtual const ToolboxMessageTree * rootModel() const = 0; protected: constexpr static int k_maxMessageSize = 100; bool selectSubMenu(int selectedRow) override; bool returnToPreviousMenu() override; virtual int maxNumberOfDisplayedRows() = 0; - virtual MessageTableCellWithMessage * leafCellAtIndex(int index) override = 0; - virtual MessageTableCellWithChevron * nodeCellAtIndex(int index) override = 0; + virtual const ToolboxMessageTree * rootModel() const = 0; + MessageTableCellWithMessage * leafCellAtIndex(int index) override = 0; + MessageTableCellWithChevron * nodeCellAtIndex(int index) override = 0; mutable ToolboxMessageTree * m_messageTreeModel; /* m_messageTreeModel points at the messageTree of the tree (describing the * whole model) where we are located. It enables to know which rows are leaves diff --git a/escher/include/escher/window.h b/escher/include/escher/window.h index 0e618083a..89a832873 100644 --- a/escher/include/escher/window.h +++ b/escher/include/escher/window.h @@ -12,9 +12,9 @@ protected: #if ESCHER_VIEW_LOGGING const char * className() const override; #endif - virtual int numberOfSubviews() const override; - virtual void layoutSubviews(bool force = false) override; - virtual View * subviewAtIndex(int index) override; + int numberOfSubviews() const override; + void layoutSubviews(bool force = false) override; + View * subviewAtIndex(int index) override; View * m_contentView; private: const Window * window() const override; diff --git a/escher/src/clipboard.cpp b/escher/src/clipboard.cpp index 446211c4b..a8551bc2b 100644 --- a/escher/src/clipboard.cpp +++ b/escher/src/clipboard.cpp @@ -1,15 +1,14 @@ #include +#include static Clipboard s_clipboard; -static inline int minInt(int x, int y) { return x < y ? x : y; } - Clipboard * Clipboard::sharedClipboard() { return &s_clipboard; } void Clipboard::store(const char * storedText, int length) { - strlcpy(m_textBuffer, storedText, length == -1 ? TextField::maxBufferSize() : minInt(TextField::maxBufferSize(), length + 1)); + strlcpy(m_textBuffer, storedText, length == -1 ? TextField::maxBufferSize() : std::min(TextField::maxBufferSize(), length + 1)); } void Clipboard::reset() { diff --git a/escher/src/expression_field.cpp b/escher/src/expression_field.cpp index 967ac940a..47eca1a43 100644 --- a/escher/src/expression_field.cpp +++ b/escher/src/expression_field.cpp @@ -1,9 +1,10 @@ #include #include #include +#include -static inline KDCoordinate minCoordinate(KDCoordinate x, KDCoordinate y) { return x < y ? x : y; } -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } +constexpr KDCoordinate ExpressionField::k_maximalHeight; +constexpr KDCoordinate ExpressionField::k_minimalHeight; ExpressionField::ExpressionField(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate) : Responder(parentResponder), @@ -117,6 +118,6 @@ bool ExpressionField::handleEventWithText(const char * text, bool indentation, b KDCoordinate ExpressionField::inputViewHeight() const { return k_separatorThickness + (editionIsInTextField() ? k_minimalHeight : - minCoordinate(k_maximalHeight, - maxCoordinate(k_minimalHeight, m_layoutField.minimalSizeForOptimalDisplay().height()))); + std::min(k_maximalHeight, + std::max(k_minimalHeight, m_layoutField.minimalSizeForOptimalDisplay().height()))); } diff --git a/escher/src/expression_view.cpp b/escher/src/expression_view.cpp index dc713c2fa..35f0f65cf 100644 --- a/escher/src/expression_view.cpp +++ b/escher/src/expression_view.cpp @@ -1,10 +1,9 @@ #include #include +#include using namespace Poincare; -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } - ExpressionView::ExpressionView(float horizontalAlignment, float verticalAlignment, KDColor textColor, KDColor backgroundColor, Poincare::Layout * selectionStart, Poincare::Layout * selectionEnd ) : m_layout(), @@ -65,7 +64,7 @@ KDSize ExpressionView::minimalSizeForOptimalDisplay() const { KDPoint ExpressionView::drawingOrigin() const { KDSize expressionSize = m_layout.layoutSize(); - return KDPoint(m_horizontalMargin + m_horizontalAlignment*(m_frame.width() - 2*m_horizontalMargin - expressionSize.width()), maxCoordinate(0, m_verticalAlignment*(m_frame.height() - expressionSize.height()))); + return KDPoint(m_horizontalMargin + m_horizontalAlignment*(m_frame.width() - 2*m_horizontalMargin - expressionSize.width()), std::max(0, m_verticalAlignment*(m_frame.height() - expressionSize.height()))); } KDPoint ExpressionView::absoluteDrawingOrigin() const { diff --git a/escher/src/layout_field.cpp b/escher/src/layout_field.cpp index 728108a0e..8bb15ff38 100644 --- a/escher/src/layout_field.cpp +++ b/escher/src/layout_field.cpp @@ -5,11 +5,10 @@ #include #include #include +#include using namespace Poincare; -static inline KDCoordinate minCoordinate(KDCoordinate x, KDCoordinate y) { return x < y ? x : y; } - LayoutField::ContentView::ContentView() : m_cursor(), m_expressionView(0.0f, 0.5f, Palette::PrimaryText, Palette::BackgroundHard, &m_selectionStart, &m_selectionEnd), @@ -335,29 +334,30 @@ bool LayoutField::handleEventWithText(const char * text, bool indentation, bool return true; } + Poincare::LayoutCursor * cursor = m_contentView.cursor(); // Handle special cases if (strcmp(text, Ion::Events::Division.text()) == 0) { - m_contentView.cursor()->addFractionLayoutAndCollapseSiblings(); + cursor->addFractionLayoutAndCollapseSiblings(); } else if (strcmp(text, Ion::Events::Exp.text()) == 0) { - m_contentView.cursor()->addEmptyExponentialLayout(); + cursor->addEmptyExponentialLayout(); } else if (strcmp(text, Ion::Events::Power.text()) == 0) { - m_contentView.cursor()->addEmptyPowerLayout(); + cursor->addEmptyPowerLayout(); } else if (strcmp(text, Ion::Events::Sqrt.text()) == 0) { - m_contentView.cursor()->addEmptySquareRootLayout(); + cursor->addEmptySquareRootLayout(); } else if (strcmp(text, Ion::Events::Square.text()) == 0) { - m_contentView.cursor()->addEmptySquarePowerLayout(); + cursor->addEmptySquarePowerLayout(); } else if (strcmp(text, Ion::Events::EE.text()) == 0) { - m_contentView.cursor()->addEmptyTenPowerLayout(); + cursor->addEmptyTenPowerLayout(); } else if ((strcmp(text, "[") == 0) || (strcmp(text, "]") == 0)) { - m_contentView.cursor()->addEmptyMatrixLayout(); + cursor->addEmptyMatrixLayout(); } else if((strcmp(text, Ion::Events::Multiplication.text())) == 0){ - m_contentView.cursor()->addMultiplicationPointLayout(); + cursor->addMultiplicationPointLayout(); } else { Expression resultExpression = Expression::Parse(text, nullptr); if (resultExpression.isUninitialized()) { // The text is not parsable (for instance, ",") and is added char by char. KDSize previousLayoutSize = minimalSizeForOptimalDisplay(); - m_contentView.cursor()->insertText(text, forceCursorRightOfText); + cursor->insertText(text, forceCursorRightOfText); reload(previousLayoutSize); return true; } @@ -431,6 +431,30 @@ void LayoutField::deleteSelection() { m_contentView.deleteSelection(); } +#define static_assert_immediately_follows(a, b) static_assert( \ + static_cast(a) + 1 == static_cast(b), \ + "Ordering error" \ +) + +#define static_assert_sequential(a, b, c, d) \ + static_assert_immediately_follows(a, b); \ + static_assert_immediately_follows(b, c); \ + static_assert_immediately_follows(c, d); + + +static_assert_sequential( + Ion::Events::Left, + Ion::Events::Up, + Ion::Events::Down, + Ion::Events::Right +); + +static inline bool IsMoveEvent(Ion::Events::Event event) { + return + static_cast(event) >= static_cast(Ion::Events::Left) && + static_cast(event) <= static_cast(Ion::Events::Right); +} + bool LayoutField::privateHandleEvent(Ion::Events::Event event) { if (m_delegate && m_delegate->layoutFieldDidReceiveEvent(this, event)) { return true; @@ -455,7 +479,7 @@ bool LayoutField::privateHandleEvent(Ion::Events::Event event) { /* if move event was not caught neither by privateHandleMoveEvent nor by * layoutFieldShouldFinishEditing, we handle it here to avoid bubbling the * event up. */ - if ((event == Ion::Events::Up || event == Ion::Events::Down || event == Ion::Events::Left || event == Ion::Events::Right) && isEditing()) { + if (IsMoveEvent(event) && isEditing()) { return true; } if ((event == Ion::Events::OK || event == Ion::Events::EXE) && !isEditing()) { @@ -508,15 +532,6 @@ bool LayoutField::privateHandleEvent(Ion::Events::Event event) { return false; } -#define static_assert_immediately_follows(a, b) static_assert( \ - static_cast(a) + 1 == static_cast(b), \ - "Ordering error" \ -) - -#define static_assert_sequential(a, b, c, d) \ - static_assert_immediately_follows(a, b); \ - static_assert_immediately_follows(b, c); \ - static_assert_immediately_follows(c, d); static_assert_sequential( LayoutCursor::Direction::Left, @@ -525,18 +540,6 @@ static_assert_sequential( LayoutCursor::Direction::Right ); -static_assert_sequential( - Ion::Events::Left, - Ion::Events::Up, - Ion::Events::Down, - Ion::Events::Right -); - -static inline bool IsMoveEvent(Ion::Events::Event event) { - return - static_cast(event) >= static_cast(Ion::Events::Left) && - static_cast(event) <= static_cast(Ion::Events::Right); -} static inline LayoutCursor::Direction DirectionForMoveEvent(Ion::Events::Event event) { assert(IsMoveEvent(event)); @@ -612,8 +615,8 @@ void LayoutField::scrollToBaselinedRect(KDRect rect, KDCoordinate baseline) { scrollToContentRect(rect, true); // Show the rect area around its baseline KDCoordinate underBaseline = rect.height() - baseline; - KDCoordinate minAroundBaseline = minCoordinate(baseline, underBaseline); - minAroundBaseline = minCoordinate(minAroundBaseline, bounds().height() / 2); + KDCoordinate minAroundBaseline = std::min(baseline, underBaseline); + minAroundBaseline = std::min(minAroundBaseline, bounds().height() / 2); KDRect balancedRect(rect.x(), rect.y() + baseline - minAroundBaseline, rect.width(), 2 * minAroundBaseline); scrollToContentRect(balancedRect, true); } diff --git a/escher/src/metric.cpp b/escher/src/metric.cpp new file mode 100644 index 000000000..1ff05788f --- /dev/null +++ b/escher/src/metric.cpp @@ -0,0 +1,33 @@ +#include + +constexpr KDCoordinate Metric::CellMargin; +constexpr KDCoordinate Metric::CommonLeftMargin; +constexpr KDCoordinate Metric::CommonRightMargin; +constexpr KDCoordinate Metric::CommonTopMargin; +constexpr KDCoordinate Metric::CommonBottomMargin; +constexpr KDCoordinate Metric::CommonLargeMargin; +constexpr KDCoordinate Metric::CommonSmallMargin; +constexpr KDCoordinate Metric::TitleBarExternHorizontalMargin; +constexpr KDCoordinate Metric::TitleBarHeight; +constexpr KDCoordinate Metric::ParameterCellHeight; +constexpr KDCoordinate Metric::ModalTopMargin; +constexpr KDCoordinate Metric::ModalBottomMargin; +constexpr KDCoordinate Metric::TableCellVerticalMargin; +constexpr KDCoordinate Metric::TableCellHorizontalMargin; +constexpr KDCoordinate Metric::TabHeight; +constexpr KDCoordinate Metric::ScrollStep; +constexpr KDCoordinate Metric::PopUpLeftMargin; +constexpr KDCoordinate Metric::PopUpRightMargin; +constexpr KDCoordinate Metric::PopUpTopMargin; +constexpr KDCoordinate Metric::ExamPopUpTopMargin; +constexpr KDCoordinate Metric::ExamPopUpBottomMargin; +constexpr KDCoordinate Metric::StoreRowHeight; +constexpr KDCoordinate Metric::ToolboxRowHeight; +constexpr KDCoordinate Metric::StackTitleHeight; +constexpr KDCoordinate Metric::FractionAndConjugateHorizontalOverflow; +constexpr KDCoordinate Metric::FractionAndConjugateHorizontalMargin; +constexpr KDCoordinate Metric::MinimalBracketAndParenthesisHeight; +constexpr KDCoordinate Metric::CellSeparatorThickness; +constexpr KDCoordinate Metric::TableSeparatorThickness; +constexpr KDCoordinate Metric::ExpressionViewHorizontalMargin; +constexpr KDCoordinate Metric::EllipsisCellWidth; diff --git a/escher/src/scroll_view.cpp b/escher/src/scroll_view.cpp index 332e9dfe2..d5617d299 100644 --- a/escher/src/scroll_view.cpp +++ b/escher/src/scroll_view.cpp @@ -4,9 +4,7 @@ extern "C" { #include } - -static inline KDCoordinate minCoordinate(KDCoordinate x, KDCoordinate y) { return x < y ? x : y; } -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } +#include ScrollView::ScrollView(View * contentView, ScrollViewDataSource * dataSource) : View(), @@ -76,8 +74,8 @@ void ScrollView::scrollToContentPoint(KDPoint p, bool allowOverscroll) { // Handle cases when the size of the view has decreased. setContentOffset(KDPoint( - minCoordinate(contentOffset().x(), maxCoordinate(minimalSizeForOptimalDisplay().width() - bounds().width(), 0)), - minCoordinate(contentOffset().y(), maxCoordinate(minimalSizeForOptimalDisplay().height() - bounds().height(), 0)))); + std::min(contentOffset().x(), std::max(minimalSizeForOptimalDisplay().width() - bounds().width(), KDCoordinate{0})), + std::min(contentOffset().y(), std::max(minimalSizeForOptimalDisplay().height() - bounds().height(), 0)))); } void ScrollView::scrollToContentRect(KDRect rect, bool allowOverscroll) { diff --git a/escher/src/scrollable_view.cpp b/escher/src/scrollable_view.cpp index 5d5e90f57..af59594af 100644 --- a/escher/src/scrollable_view.cpp +++ b/escher/src/scrollable_view.cpp @@ -1,9 +1,7 @@ #include #include #include - -static inline KDCoordinate minCoordinate(KDCoordinate x, KDCoordinate y) { return x < y ? x : y; } -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } +#include ScrollableView::ScrollableView(Responder * parentResponder, View * view, ScrollViewDataSource * dataSource) : Responder(parentResponder), @@ -17,25 +15,25 @@ bool ScrollableView::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::Left) { KDCoordinate movementToEdge = contentOffset().x(); if (movementToEdge > 0) { - translation = KDPoint(-minCoordinate(Metric::ScrollStep, movementToEdge), 0); + translation = KDPoint(-std::min(Metric::ScrollStep, movementToEdge), 0); } } if (event == Ion::Events::Right) { KDCoordinate movementToEdge = minimalSizeForOptimalDisplay().width() - bounds().width() - contentOffset().x(); if (movementToEdge > 0) { - translation = KDPoint(minCoordinate(Metric::ScrollStep, movementToEdge), 0); + translation = KDPoint(std::min(Metric::ScrollStep, movementToEdge), 0); } } if (event == Ion::Events::Up) { KDCoordinate movementToEdge = contentOffset().y(); if (movementToEdge > 0) { - translation = KDPoint(0, -minCoordinate(Metric::ScrollStep, movementToEdge)); + translation = KDPoint(0, -std::min(Metric::ScrollStep, movementToEdge)); } } if (event == Ion::Events::Down) { KDCoordinate movementToEdge = minimalSizeForOptimalDisplay().height() - bounds().height() - contentOffset().y(); if (movementToEdge > 0) { - translation = KDPoint(0, minCoordinate(Metric::ScrollStep, movementToEdge)); + translation = KDPoint(0, std::min(Metric::ScrollStep, movementToEdge)); } } if (translation != KDPointZero) { @@ -51,7 +49,7 @@ void ScrollableView::reloadScroll(bool forceReLayout) { KDSize ScrollableView::contentSize() const { KDSize viewSize = ScrollView::contentSize(); - KDCoordinate viewWidth = maxCoordinate(viewSize.width(), maxContentWidthDisplayableWithoutScrolling()); - KDCoordinate viewHeight = maxCoordinate(viewSize.height(), maxContentHeightDisplayableWithoutScrolling()); + KDCoordinate viewWidth = std::max(viewSize.width(), maxContentWidthDisplayableWithoutScrolling()); + KDCoordinate viewHeight = std::max(viewSize.height(), maxContentHeightDisplayableWithoutScrolling()); return KDSize(viewWidth, viewHeight); } diff --git a/escher/src/table_cell.cpp b/escher/src/table_cell.cpp index 193296a44..f9c60e8e6 100644 --- a/escher/src/table_cell.cpp +++ b/escher/src/table_cell.cpp @@ -1,9 +1,7 @@ #include #include #include - -static inline KDCoordinate minCoordinate(KDCoordinate x, KDCoordinate y) { return x < y ? x : y; } -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } +#include TableCell::TableCell(Layout layout) : Bordered(), @@ -95,21 +93,21 @@ void TableCell::layoutSubviews(bool force) { KDCoordinate y = k_separatorThickness; if (label) { y += k_verticalMargin; - KDCoordinate labelHeight = minCoordinate(labelSize.height(), height - y - k_separatorThickness - k_verticalMargin); + KDCoordinate labelHeight = std::min(labelSize.height(), height - y - k_separatorThickness - k_verticalMargin); label->setFrame(KDRect(horizontalMargin, y, width-2*horizontalMargin, labelHeight), force); y += labelHeight + k_verticalMargin; } horizontalMargin = k_separatorThickness + k_horizontalMargin; - y = maxCoordinate(y, height - k_separatorThickness - withMargin(accessorySize.height(), Metric::TableCellVerticalMargin) - withMargin(subAccessorySize.height(), 0)); + y = std::max(y, height - k_separatorThickness - withMargin(accessorySize.height(), Metric::TableCellVerticalMargin) - withMargin(subAccessorySize.height(), 0)); if (subAccessory) { - KDCoordinate subAccessoryHeight = minCoordinate(subAccessorySize.height(), height - y - k_separatorThickness - Metric::TableCellVerticalMargin); + KDCoordinate subAccessoryHeight = std::min(subAccessorySize.height(), height - y - k_separatorThickness - Metric::TableCellVerticalMargin); accessory->setFrame(KDRect(horizontalMargin, y, width - 2*horizontalMargin, subAccessoryHeight), force); y += subAccessoryHeight; } horizontalMargin = k_separatorThickness + accessoryMargin(); - y = maxCoordinate(y, height - k_separatorThickness - withMargin(accessorySize.height(), Metric::TableCellVerticalMargin)); + y = std::max(y, height - k_separatorThickness - withMargin(accessorySize.height(), Metric::TableCellVerticalMargin)); if (accessory) { - KDCoordinate accessoryHeight = minCoordinate(accessorySize.height(), height - y - k_separatorThickness - Metric::TableCellVerticalMargin); + KDCoordinate accessoryHeight = std::min(accessorySize.height(), height - y - k_separatorThickness - Metric::TableCellVerticalMargin); accessory->setFrame(KDRect(horizontalMargin, y, width - 2*horizontalMargin, accessoryHeight), force); } } else { @@ -137,29 +135,29 @@ void TableCell::layoutSubviews(bool force) { KDCoordinate verticalMargin = k_separatorThickness; KDCoordinate x = 0; KDCoordinate labelX = k_separatorThickness + labelMargin(); - KDCoordinate subAccessoryX = maxCoordinate(k_separatorThickness + k_horizontalMargin, width - k_separatorThickness - withMargin(accessorySize.width(), accessoryMargin()) - withMargin(subAccessorySize.width(), 0)); - KDCoordinate accessoryX = maxCoordinate(k_separatorThickness + accessoryMargin(), width - k_separatorThickness - withMargin(accessorySize.width(), accessoryMargin())); + KDCoordinate subAccessoryX = std::max(k_separatorThickness + k_horizontalMargin, width - k_separatorThickness - withMargin(accessorySize.width(), accessoryMargin()) - withMargin(subAccessorySize.width(), 0)); + KDCoordinate accessoryX = std::max(k_separatorThickness + accessoryMargin(), width - k_separatorThickness - withMargin(accessorySize.width(), accessoryMargin())); if (label) { x = labelX; - KDCoordinate labelWidth = minCoordinate(labelSize.width(), width - x - k_separatorThickness - labelMargin()); + KDCoordinate labelWidth = std::min(labelSize.width(), width - x - k_separatorThickness - labelMargin()); if (m_layout == Layout::HorizontalRightOverlap) { - labelWidth = minCoordinate(labelWidth, subAccessoryX - x - labelMargin()); + labelWidth = std::min(labelWidth, subAccessoryX - x - labelMargin()); } label->setFrame(KDRect(x, verticalMargin, labelWidth, height-2*verticalMargin), force); x += labelWidth + labelMargin(); } if (subAccessory) { - x = maxCoordinate(x, subAccessoryX); - KDCoordinate subAccessoryWidth = minCoordinate(subAccessorySize.width(), width - x - k_separatorThickness - k_horizontalMargin); + x = std::max(x, subAccessoryX); + KDCoordinate subAccessoryWidth = std::min(subAccessorySize.width(), width - x - k_separatorThickness - k_horizontalMargin); if (m_layout == Layout::HorizontalRightOverlap) { - subAccessoryWidth = minCoordinate(subAccessoryWidth, accessoryX - x); + subAccessoryWidth = std::min(subAccessoryWidth, accessoryX - x); } subAccessory->setFrame(KDRect(x, verticalMargin, subAccessoryWidth, height-2*verticalMargin), force); x += subAccessoryWidth; } if (accessory) { - x = maxCoordinate(x, accessoryX); - KDCoordinate accessoryWidth = minCoordinate(accessorySize.width(), width - x - k_separatorThickness - accessoryMargin()); + x = std::max(x, accessoryX); + KDCoordinate accessoryWidth = std::min(accessorySize.width(), width - x - k_separatorThickness - accessoryMargin()); accessory->setFrame(KDRect(x, verticalMargin, accessoryWidth, height-2*verticalMargin), force); } } diff --git a/escher/src/table_view.cpp b/escher/src/table_view.cpp index f4c72317e..01ea22a2d 100644 --- a/escher/src/table_view.cpp +++ b/escher/src/table_view.cpp @@ -4,8 +4,7 @@ extern "C" { #include } - -#define MIN(x,y) ((x)<(y) ? (x) : (y)) +#include TableView::TableView(TableViewDataSource * dataSource, ScrollViewDataSource * scrollDataSource) : ScrollView(&m_contentView, scrollDataSource), @@ -200,7 +199,7 @@ int TableView::ContentView::numberOfFullyDisplayableColumns() const { int TableView::ContentView::numberOfDisplayableRows() const { int rowOffset = rowsScrollingOffset(); int displayedHeightWithOffset = m_dataSource->indexFromCumulatedHeight(m_tableView->bounds().height() + m_tableView->contentOffset().y()); - return MIN( + return std::min( m_dataSource->numberOfRows(), displayedHeightWithOffset + 1 ) - rowOffset; @@ -209,7 +208,7 @@ int TableView::ContentView::numberOfDisplayableRows() const { int TableView::ContentView::numberOfDisplayableColumns() const { int columnOffset = columnsScrollingOffset(); int displayedWidthWithOffset = m_dataSource->indexFromCumulatedWidth(m_tableView->bounds().width() + m_tableView->contentOffset().x()); - return MIN( + return std::min( m_dataSource->numberOfColumns(), displayedWidthWithOffset + 1 ) - columnOffset; diff --git a/escher/src/text_area.cpp b/escher/src/text_area.cpp index 837e341b7..5081a74d4 100644 --- a/escher/src/text_area.cpp +++ b/escher/src/text_area.cpp @@ -8,10 +8,7 @@ #include #include #include - -static inline const char * maxPointer(const char * x, const char * y) { return x > y ? x : y; } -static inline const char * minPointer(const char * x, const char * y) { return x < y ? x : y; } -static inline size_t minSizeT(size_t x, size_t y) { return x < y ? x : y; } +#include /* TextArea */ @@ -239,7 +236,7 @@ const char * TextArea::Text::pointerAtPosition(Position p) { for (Line l : *this) { if (p.line() == y) { const char * result = UTF8Helper::CodePointAtGlyphOffset(l.text(), p.column()); - return minPointer(result, l.text() + l.charLength()); + return std::min(result, l.text() + l.charLength()); } y++; } @@ -445,13 +442,13 @@ void TextArea::ContentView::drawStringAt(KDContext * ctx, int line, int column, m_font, textColor, backgroundColor, - drawSelection ? (selectionStart >= text ? minSizeT(length, selectionStart - text) : 0) : length + drawSelection ? (selectionStart >= text ? std::min(length, selectionStart - text) : 0) : length ); if (!drawSelection) { return; } - const char * highlightedDrawStart = maxPointer(selectionStart, text); - size_t highlightedDrawLength = minSizeT(selectionEnd - highlightedDrawStart, length - (highlightedDrawStart - text)); + const char * highlightedDrawStart = std::max(selectionStart, text); + size_t highlightedDrawLength = std::min(selectionEnd - highlightedDrawStart, length - (highlightedDrawStart - text)); nextPoint = ctx->drawString( highlightedDrawStart, diff --git a/escher/src/text_field.cpp b/escher/src/text_field.cpp index b9043448d..3fbd5eaa3 100644 --- a/escher/src/text_field.cpp +++ b/escher/src/text_field.cpp @@ -5,8 +5,8 @@ #include #include #include +#include -static inline int minInt(int x, int y) { return x < y ? x : y; } static char s_draftTextBuffer[TextField::maxBufferSize()]; /* TextField::ContentView */ @@ -84,7 +84,7 @@ void TextField::ContentView::setText(const char * text) { buffer[0] = 0; return; } - int textLength = minInt(textRealLength, maxBufferSize - 1); + int textLength = std::min(textRealLength, maxBufferSize - 1); // Copy the text strlcpy(buffer, text, maxBufferSize); // Update the draft text length diff --git a/escher/src/text_input.cpp b/escher/src/text_input.cpp index 0bc583bc7..6e573a045 100644 --- a/escher/src/text_input.cpp +++ b/escher/src/text_input.cpp @@ -2,12 +2,10 @@ #include #include #include +#include /* TextInput::ContentView */ -static inline const char * minCharPointer(const char * x, const char * y) { return x < y ? x : y; } -static inline const char * maxCharPointer(const char * x, const char * y) { return x > y ? x : y; } - void TextInput::ContentView::setFont(const KDFont * font) { m_font = font; markRectAsDirty(bounds()); @@ -16,7 +14,7 @@ void TextInput::ContentView::setFont(const KDFont * font) { void TextInput::ContentView::setCursorLocation(const char * location) { assert(location != nullptr); assert(location >= editedText()); - const char * adjustedLocation = minCharPointer(location, editedText() + editedTextLength()); + const char * adjustedLocation = std::min(location, editedText() + editedTextLength()); m_cursorLocation = adjustedLocation; layoutSubviews(); } @@ -131,7 +129,7 @@ bool TextInput::removePreviousGlyph() { bool TextInput::setCursorLocation(const char * location) { assert(location != nullptr); - const char * adjustedLocation = maxCharPointer(location, text()); + const char * adjustedLocation = std::max(location, text()); willSetCursorLocation(&adjustedLocation); contentView()->setCursorLocation(adjustedLocation); scrollToCursor(); diff --git a/escher/src/warning_controller.cpp b/escher/src/warning_controller.cpp index dcad7c554..5ca4e8526 100644 --- a/escher/src/warning_controller.cpp +++ b/escher/src/warning_controller.cpp @@ -1,7 +1,6 @@ #include #include - -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } +#include WarningController::ContentView::ContentView() : SolidColorView(KDColorBlack), @@ -46,7 +45,7 @@ KDSize WarningController::ContentView::minimalSizeForOptimalDisplay() const { } assert(numberOfSubviews() == 2); KDSize textSize2 = m_textView2.minimalSizeForOptimalDisplay(); - return KDSize(maxCoordinate(textSize1.width(), textSize2.width()) + k_horizontalMargin, + return KDSize(std::max(textSize1.width(), textSize2.width()) + k_horizontalMargin, textSize1.height() + textSize2.height() + 2*k_topAndBottomMargin + k_middleMargin); } diff --git a/ion/include/ion/events.h b/ion/include/ion/events.h index 28e7c5122..2b72c6207 100644 --- a/ion/include/ion/events.h +++ b/ion/include/ion/events.h @@ -18,10 +18,10 @@ public: constexpr Event(int i) : m_id(i){} // TODO: Assert here that i>=0 && i<255 constexpr explicit operator uint8_t() const { return m_id; } -#if DEBUG +#ifndef NDEBUG const char * name() const; #endif - Event(Keyboard::Key key, bool shift, bool alpha); + Event(Keyboard::Key key, bool shift, bool alpha, bool lock); bool operator==(const Event & other) const { return (m_id == other.m_id); diff --git a/ion/include/ion/keyboard/layout_B2/layout_events.h b/ion/include/ion/keyboard/layout_B2/layout_events.h index b67988907..4d0c1e436 100644 --- a/ion/include/ion/keyboard/layout_B2/layout_events.h +++ b/ion/include/ion/keyboard/layout_B2/layout_events.h @@ -51,7 +51,7 @@ static constexpr EventData s_dataForEvent[4*Event::PageSize] = { U(), U(), U(), TL(), U(), U(), }; -#if DEBUG +#ifndef NDEBUG static constexpr const char * s_nameForEvent[255] = { // Plain diff --git a/ion/include/ion/keyboard/layout_B3/layout_events.h b/ion/include/ion/keyboard/layout_B3/layout_events.h index 8124c3e9d..538e68e0d 100644 --- a/ion/include/ion/keyboard/layout_B3/layout_events.h +++ b/ion/include/ion/keyboard/layout_B3/layout_events.h @@ -51,7 +51,7 @@ static constexpr EventData s_dataForEvent[4*Event::PageSize] = { U(), U(), U(), U(), U(), U(), }; -#if DEBUG +#ifndef NDEBUG static constexpr const char * s_nameForEvent[255] = { // Plain diff --git a/ion/src/blackbox/events.cpp b/ion/src/blackbox/events.cpp index 1c9f730f3..6dd8cde71 100644 --- a/ion/src/blackbox/events.cpp +++ b/ion/src/blackbox/events.cpp @@ -25,7 +25,7 @@ Event getEvent(int * timeout) { char filename[32]; sprintf(filename, "event%d.png", sEventCount); Ion::Display::Blackbox::writeFrameBufferToFile(filename); -#if DEBUG +#ifndef NDEBUG printf("Event %d is %s\n", sEventCount, event.name()); #endif } diff --git a/ion/src/device/shared/boot/rt0.cpp b/ion/src/device/shared/boot/rt0.cpp index 45a003f40..38ad5e9e6 100644 --- a/ion/src/device/shared/boot/rt0.cpp +++ b/ion/src/device/shared/boot/rt0.cpp @@ -19,11 +19,11 @@ extern "C" { } void __attribute__((noinline)) abort() { -#if DEBUG +#ifdef NDEBUG + Ion::Device::Reset::core(); +#else while (1) { } -#else - Ion::Device::Reset::core(); #endif } diff --git a/ion/src/device/shared/drivers/internal_flash.cpp b/ion/src/device/shared/drivers/internal_flash.cpp index 9ff5e1432..cd8fa60bd 100644 --- a/ion/src/device/shared/drivers/internal_flash.cpp +++ b/ion/src/device/shared/drivers/internal_flash.cpp @@ -2,6 +2,7 @@ #include #include #include +#include namespace Ion { namespace Device { @@ -96,11 +97,6 @@ static inline ptrdiff_t byte_offset(void * p1, void * p2) { return reinterpret_cast(p2) - reinterpret_cast(p1); } -template -static inline T min(T i, T j) { - return (i( + uint8_t * headerDataEnd = std::min( headerStart + sizeof(MemoryAccessType), // Either at the end of the header headerDataStart + length // or whenever src runs out of data ); diff --git a/ion/src/device/shared/usb/calculator.h b/ion/src/device/shared/usb/calculator.h index 2532356e3..6dd9679f5 100644 --- a/ion/src/device/shared/usb/calculator.h +++ b/ion/src/device/shared/usb/calculator.h @@ -117,11 +117,11 @@ public: uint32_t addressPointer() const { return m_dfuInterface.addressPointer(); } bool isErasingAndWriting() const { return m_dfuInterface.isErasingAndWriting(); } protected: - virtual Descriptor * descriptor(uint8_t type, uint8_t index) override; - virtual void setActiveConfiguration(uint8_t configurationIndex) override { + Descriptor * descriptor(uint8_t type, uint8_t index) override; + void setActiveConfiguration(uint8_t configurationIndex) override { assert(configurationIndex == k_bConfigurationValue); } - virtual uint8_t getActiveConfiguration() override { + uint8_t getActiveConfiguration() override { return k_bConfigurationValue; } bool processSetupInRequest(SetupPacket * request, uint8_t * transferBuffer, uint16_t * transferBufferLength, uint16_t transferBufferMaxLength) override; diff --git a/ion/src/device/shared/usb/stack/descriptor/bos_descriptor.h b/ion/src/device/shared/usb/stack/descriptor/bos_descriptor.h index 4c68bb327..25529c0e5 100644 --- a/ion/src/device/shared/usb/stack/descriptor/bos_descriptor.h +++ b/ion/src/device/shared/usb/stack/descriptor/bos_descriptor.h @@ -22,7 +22,7 @@ public: } protected: void push(Channel * c) const override; - virtual uint8_t bLength() const override; + uint8_t bLength() const override; private: uint16_t m_wTotalLength; uint8_t m_bNumDeviceCaps; diff --git a/ion/src/device/shared/usb/stack/descriptor/configuration_descriptor.h b/ion/src/device/shared/usb/stack/descriptor/configuration_descriptor.h index aea863c43..9f994b6e3 100644 --- a/ion/src/device/shared/usb/stack/descriptor/configuration_descriptor.h +++ b/ion/src/device/shared/usb/stack/descriptor/configuration_descriptor.h @@ -30,7 +30,7 @@ public: } protected: void push(Channel * c) const override; - virtual uint8_t bLength() const override; + uint8_t bLength() const override; private: uint16_t m_wTotalLength; uint8_t m_bNumInterfaces; diff --git a/ion/src/device/shared/usb/stack/descriptor/device_capability_descriptor.h b/ion/src/device/shared/usb/stack/descriptor/device_capability_descriptor.h index 435358a65..f434352f2 100644 --- a/ion/src/device/shared/usb/stack/descriptor/device_capability_descriptor.h +++ b/ion/src/device/shared/usb/stack/descriptor/device_capability_descriptor.h @@ -19,7 +19,7 @@ public: } protected: void push(Channel * c) const override; - virtual uint8_t bLength() const override; + uint8_t bLength() const override; private: uint8_t m_bDeviceCapabilityType; }; diff --git a/ion/src/device/shared/usb/stack/descriptor/device_descriptor.h b/ion/src/device/shared/usb/stack/descriptor/device_descriptor.h index 840c01da6..3b526f43f 100644 --- a/ion/src/device/shared/usb/stack/descriptor/device_descriptor.h +++ b/ion/src/device/shared/usb/stack/descriptor/device_descriptor.h @@ -39,7 +39,7 @@ public: } protected: void push(Channel * c) const override; - virtual uint8_t bLength() const override; + uint8_t bLength() const override; private: uint16_t m_bcdUSB; uint8_t m_bDeviceClass; diff --git a/ion/src/device/shared/usb/stack/descriptor/dfu_functional_descriptor.h b/ion/src/device/shared/usb/stack/descriptor/dfu_functional_descriptor.h index fb04a824a..604392895 100644 --- a/ion/src/device/shared/usb/stack/descriptor/dfu_functional_descriptor.h +++ b/ion/src/device/shared/usb/stack/descriptor/dfu_functional_descriptor.h @@ -23,7 +23,7 @@ public: } protected: void push(Channel * c) const override; - virtual uint8_t bLength() const override; + uint8_t bLength() const override; private: uint8_t m_bmAttributes; uint16_t m_wDetachTimeOut; diff --git a/ion/src/device/shared/usb/stack/descriptor/interface_descriptor.h b/ion/src/device/shared/usb/stack/descriptor/interface_descriptor.h index ef8481289..6a49bfb8a 100644 --- a/ion/src/device/shared/usb/stack/descriptor/interface_descriptor.h +++ b/ion/src/device/shared/usb/stack/descriptor/interface_descriptor.h @@ -36,7 +36,7 @@ public: } protected: void push(Channel * c) const override; - virtual uint8_t bLength() const override; + uint8_t bLength() const override; private: uint8_t m_bInterfaceNumber; uint8_t m_bAlternateSetting; diff --git a/ion/src/device/shared/usb/stack/descriptor/language_id_string_descriptor.h b/ion/src/device/shared/usb/stack/descriptor/language_id_string_descriptor.h index 198befac8..0f72abb91 100644 --- a/ion/src/device/shared/usb/stack/descriptor/language_id_string_descriptor.h +++ b/ion/src/device/shared/usb/stack/descriptor/language_id_string_descriptor.h @@ -15,7 +15,7 @@ public: Descriptor(0x03) { } protected: void push(Channel * c) const override; - virtual uint8_t bLength() const override; + uint8_t bLength() const override; }; } diff --git a/ion/src/device/shared/usb/stack/descriptor/microsoft_os_string_descriptor.h b/ion/src/device/shared/usb/stack/descriptor/microsoft_os_string_descriptor.h index 69ce1a33d..dfe3a7ab2 100644 --- a/ion/src/device/shared/usb/stack/descriptor/microsoft_os_string_descriptor.h +++ b/ion/src/device/shared/usb/stack/descriptor/microsoft_os_string_descriptor.h @@ -17,7 +17,7 @@ public: } protected: void push(Channel * c) const override; - virtual uint8_t bLength() const override; + uint8_t bLength() const override; private: uint8_t m_bMSVendorCode; uint8_t m_bPad; diff --git a/ion/src/device/shared/usb/stack/descriptor/platform_device_capability_descriptor.h b/ion/src/device/shared/usb/stack/descriptor/platform_device_capability_descriptor.h index 3c35dc11d..d2c425d4a 100644 --- a/ion/src/device/shared/usb/stack/descriptor/platform_device_capability_descriptor.h +++ b/ion/src/device/shared/usb/stack/descriptor/platform_device_capability_descriptor.h @@ -33,7 +33,7 @@ public: } protected: void push(Channel * c) const override; - virtual uint8_t bLength() const override; + uint8_t bLength() const override; private: constexpr static uint8_t k_platformCapabilityUUIDSize = 16; uint8_t m_bReserved; diff --git a/ion/src/device/shared/usb/stack/descriptor/string_descriptor.h b/ion/src/device/shared/usb/stack/descriptor/string_descriptor.h index e2f5ea37c..1391c4aec 100644 --- a/ion/src/device/shared/usb/stack/descriptor/string_descriptor.h +++ b/ion/src/device/shared/usb/stack/descriptor/string_descriptor.h @@ -16,7 +16,7 @@ public: } protected: void push(Channel * c) const override; - virtual uint8_t bLength() const override; + uint8_t bLength() const override; private: const char * m_string; }; diff --git a/ion/src/device/shared/usb/stack/descriptor/url_descriptor.h b/ion/src/device/shared/usb/stack/descriptor/url_descriptor.h index 3552201a2..7dee33e7c 100644 --- a/ion/src/device/shared/usb/stack/descriptor/url_descriptor.h +++ b/ion/src/device/shared/usb/stack/descriptor/url_descriptor.h @@ -23,7 +23,7 @@ public: } protected: void push(Channel * c) const override; - virtual uint8_t bLength() const override; + uint8_t bLength() const override; private: uint8_t m_bScheme; const char * m_string; diff --git a/ion/src/device/shared/usb/stack/descriptor/webusb_platform_descriptor.h b/ion/src/device/shared/usb/stack/descriptor/webusb_platform_descriptor.h index a1b5bcb4b..549bcdae2 100644 --- a/ion/src/device/shared/usb/stack/descriptor/webusb_platform_descriptor.h +++ b/ion/src/device/shared/usb/stack/descriptor/webusb_platform_descriptor.h @@ -18,7 +18,7 @@ public: } protected: void push(Channel * c) const override; - virtual uint8_t bLength() const override; + uint8_t bLength() const override; private: /* Little-endian encoding of {3408B638-09A9-47A0-8BFD-A0768815B665}. * See https://wicg.github.io/webusb/#webusb-platform-capability-descriptor */ diff --git a/ion/src/device/shared/usb/stack/endpoint0.cpp b/ion/src/device/shared/usb/stack/endpoint0.cpp index 4e1d4e980..b97607e1b 100644 --- a/ion/src/device/shared/usb/stack/endpoint0.cpp +++ b/ion/src/device/shared/usb/stack/endpoint0.cpp @@ -4,8 +4,7 @@ #include "device.h" #include "interface.h" #include "request_recipient.h" - -#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#include namespace Ion { namespace Device { @@ -98,7 +97,7 @@ void Endpoint0::readAndDispatchSetupPacket() { }; m_request = SetupPacket(m_largeBuffer); - uint16_t maxBufferLength = MIN(m_request.wLength(), MaxTransferSize); + uint16_t maxBufferLength = std::min(m_request.wLength(), MaxTransferSize); // Forward the request to the request recipient uint8_t type = static_cast(m_request.recipientType()); @@ -261,7 +260,7 @@ void Endpoint0::clearForOutTransactions(uint16_t wLength) { int Endpoint0::receiveSomeData() { // If it is the first chunk of data to be received, m_transferBufferLength is 0. - uint16_t packetSize = MIN(k_maxPacketSize, m_request.wLength() - m_transferBufferLength); + uint16_t packetSize = std::min(k_maxPacketSize, m_request.wLength() - m_transferBufferLength); uint16_t sizeOfPacketRead = readPacket(m_largeBuffer + m_transferBufferLength, packetSize); if (sizeOfPacketRead != packetSize) { stallTransaction(); @@ -273,7 +272,7 @@ int Endpoint0::receiveSomeData() { uint16_t Endpoint0::readPacket(void * buffer, uint16_t length) { uint32_t * buffer32 = (uint32_t *) buffer; - uint16_t buffer32Length = MIN(length, m_receivedPacketSize); + uint16_t buffer32Length = std::min(length, m_receivedPacketSize); int i; // The RX FIFO is read 4 bytes by 4 bytes diff --git a/ion/src/device/shared/usb/stack/endpoint0.h b/ion/src/device/shared/usb/stack/endpoint0.h index a0ef41686..42d39dbef 100644 --- a/ion/src/device/shared/usb/stack/endpoint0.h +++ b/ion/src/device/shared/usb/stack/endpoint0.h @@ -23,7 +23,7 @@ public: }; constexpr static int k_maxPacketSize = 64; - constexpr static int MaxTransferSize = 2048; + constexpr static uint16_t MaxTransferSize = 2048; constexpr Endpoint0(RequestRecipient * device, RequestRecipient * interface) : m_forceNAK(false), diff --git a/ion/src/shared/dummy/events_modifier.cpp b/ion/src/shared/dummy/events_modifier.cpp deleted file mode 100644 index d1ba3930c..000000000 --- a/ion/src/shared/dummy/events_modifier.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include - -namespace Ion { -namespace Events { - -ShiftAlphaStatus shiftAlphaStatus() { - return ShiftAlphaStatus::Default; -} - -void setShiftAlphaStatus(ShiftAlphaStatus s) { -} - -bool isShiftActive() { - return false; -} - -bool isAlphaActive() { - return false; -} - -void updateModifiersFromEvent(Event e) { -} - -} -} diff --git a/ion/src/shared/dummy/keyboard.cpp b/ion/src/shared/dummy/keyboard.cpp deleted file mode 100644 index 4adff6524..000000000 --- a/ion/src/shared/dummy/keyboard.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include - -namespace Ion { -namespace Keyboard { - -State scan() { - return 0x00000000000000; -} - -} -} diff --git a/ion/src/shared/events.cpp b/ion/src/shared/events.cpp index 6a62db538..519c4acd3 100644 --- a/ion/src/shared/events.cpp +++ b/ion/src/shared/events.cpp @@ -15,7 +15,7 @@ const char * EventData::text() const { return m_data; } -Event::Event(Keyboard::Key key, bool shift, bool alpha) { +Event::Event(Keyboard::Key key, bool shift, bool alpha, bool lock) { // We're mapping a key, shift and alpha to an event // This can be a bit more complicated than it seems since we want to fall back: // for example, alpha-up is just plain up. @@ -41,6 +41,10 @@ Event::Event(Keyboard::Key key, bool shift, bool alpha) { m_id = offset + (int)key; } while (offset > 0 && !s_dataForEvent[m_id].isDefined() && m_id < 4*PageSize); + //If we press percent in alphalock, change to backspace + if (m_id == static_cast(Ion::Events::Percent) && lock){ + m_id = static_cast(Ion::Events::Backspace); + } assert(m_id != Events::None.m_id); } diff --git a/ion/src/shared/events_keyboard.cpp b/ion/src/shared/events_keyboard.cpp index 6edfadea9..f9535dae3 100644 --- a/ion/src/shared/events_keyboard.cpp +++ b/ion/src/shared/events_keyboard.cpp @@ -73,7 +73,8 @@ Event getEvent(int * timeout) { Keyboard::Key key = (Keyboard::Key)(63-__builtin_clzll(keysSeenTransitionningFromUpToDown)); bool shift = isShiftActive() || state.keyDown(Keyboard::Key::Shift); bool alpha = isAlphaActive() || state.keyDown(Keyboard::Key::Alpha); - Event event(key, shift, alpha); + bool lock = isLockActive(); + Event event(key, shift, alpha, lock); sLastEventShift = shift; sLastEventAlpha = alpha; updateModifiersFromEvent(event); diff --git a/ion/src/shared/events_modifier.cpp b/ion/src/shared/events_modifier.cpp index 54ba7d4c7..04fc1936d 100644 --- a/ion/src/shared/events_modifier.cpp +++ b/ion/src/shared/events_modifier.cpp @@ -29,6 +29,10 @@ bool isAlphaActive() { return sShiftAlphaStatus == ShiftAlphaStatus::Alpha || sShiftAlphaStatus == ShiftAlphaStatus::ShiftAlpha || sShiftAlphaStatus == ShiftAlphaStatus::AlphaLock || sShiftAlphaStatus == ShiftAlphaStatus::ShiftAlphaLock; } +bool isLockActive() { + return sShiftAlphaStatus == ShiftAlphaStatus::AlphaLock || sShiftAlphaStatus == ShiftAlphaStatus::ShiftAlphaLock; +} + void setLongRepetition(bool longRepetition) { sLongRepetition = longRepetition; } diff --git a/ion/src/shared/tools/Makefile b/ion/src/shared/tools/Makefile index 081339af1..b9976d268 100644 --- a/ion/src/shared/tools/Makefile +++ b/ion/src/shared/tools/Makefile @@ -1,3 +1,3 @@ $(BUILD_DIR)/ion/src/shared/tools/event_%: ion/src/shared/tools/event_%.cpp ion/src/shared/events.cpp @echo "HOSTCXX $@" - @$(HOSTCXX) -std=c++11 -Iion/include -DDEBUG=1 $^ -o $@ + @$(HOSTCXX) -std=c++11 -Iion/include $^ -o $@ diff --git a/ion/src/shared/unicode/utf8_helper.cpp b/ion/src/shared/unicode/utf8_helper.cpp index 0f22a1380..07c5c5838 100644 --- a/ion/src/shared/unicode/utf8_helper.cpp +++ b/ion/src/shared/unicode/utf8_helper.cpp @@ -2,11 +2,10 @@ #include #include #include +#include namespace UTF8Helper { -static inline size_t minSizeT(size_t x, size_t y) { return x < y ? x : y; } - int CountOccurrences(const char * s, CodePoint c) { assert(c != UCodePointNull); int count = 0; @@ -174,7 +173,8 @@ size_t CopyUntilCodePoint(char * dst, size_t dstSize, const char * src, CodePoin codePointPointer = decoder.stringPosition(); codePoint = decoder.nextCodePoint(); } - size_t copySize = minSizeT(dstSize - 1, codePointPointer - src); + assert(codePointPointer >= src); + size_t copySize = std::min(dstSize - 1, static_cast(codePointPointer - src)); assert(UTF8Helper::CodePointIs(src + copySize, 0) || UTF8Helper::CodePointIs(src + copySize, c)); memmove(dst, src, copySize); assert(copySize < dstSize); diff --git a/ion/src/simulator/Makefile b/ion/src/simulator/Makefile index a0b4645fb..9ea96074d 100644 --- a/ion/src/simulator/Makefile +++ b/ion/src/simulator/Makefile @@ -1,8 +1,4 @@ -ion_src += $(addprefix ion/src/shared/, \ - crc32.cpp \ - power.cpp \ - random.cpp \ - timing.cpp \ +ion_src += $(addprefix ion/src/simulator/shared/, \ dummy/backlight.cpp \ dummy/battery.cpp \ dummy/display.cpp \ @@ -12,10 +8,8 @@ ion_src += $(addprefix ion/src/shared/, \ dummy/serial_number.cpp \ dummy/stack.cpp \ dummy/usb.cpp \ -) - -ion_src += $(addprefix ion/src/simulator/shared/, \ console_stdio.cpp:-consoledisplay \ + crc32.cpp \ display.cpp:-headless \ events_keyboard.cpp:-headless \ events_stdin.cpp:+headless \ @@ -26,6 +20,9 @@ ion_src += $(addprefix ion/src/simulator/shared/, \ layout.cpp:-headless \ main_headless.cpp:+headless \ main_sdl.cpp:-headless \ + power.cpp \ + random.cpp \ + timing.cpp \ ) include ion/src/simulator/$(TARGET)/Makefile diff --git a/ion/src/shared/crc32.cpp b/ion/src/simulator/shared/crc32.cpp similarity index 100% rename from ion/src/shared/crc32.cpp rename to ion/src/simulator/shared/crc32.cpp diff --git a/ion/src/shared/dummy/backlight.cpp b/ion/src/simulator/shared/dummy/backlight.cpp similarity index 100% rename from ion/src/shared/dummy/backlight.cpp rename to ion/src/simulator/shared/dummy/backlight.cpp diff --git a/ion/src/shared/dummy/battery.cpp b/ion/src/simulator/shared/dummy/battery.cpp similarity index 100% rename from ion/src/shared/dummy/battery.cpp rename to ion/src/simulator/shared/dummy/battery.cpp diff --git a/ion/src/shared/dummy/display.cpp b/ion/src/simulator/shared/dummy/display.cpp similarity index 100% rename from ion/src/shared/dummy/display.cpp rename to ion/src/simulator/shared/dummy/display.cpp diff --git a/ion/src/shared/dummy/exam_mode.cpp b/ion/src/simulator/shared/dummy/exam_mode.cpp similarity index 100% rename from ion/src/shared/dummy/exam_mode.cpp rename to ion/src/simulator/shared/dummy/exam_mode.cpp diff --git a/ion/src/shared/dummy/fcc_id.cpp b/ion/src/simulator/shared/dummy/fcc_id.cpp similarity index 100% rename from ion/src/shared/dummy/fcc_id.cpp rename to ion/src/simulator/shared/dummy/fcc_id.cpp diff --git a/ion/src/shared/dummy/led.cpp b/ion/src/simulator/shared/dummy/led.cpp similarity index 100% rename from ion/src/shared/dummy/led.cpp rename to ion/src/simulator/shared/dummy/led.cpp diff --git a/ion/src/shared/dummy/serial_number.cpp b/ion/src/simulator/shared/dummy/serial_number.cpp similarity index 100% rename from ion/src/shared/dummy/serial_number.cpp rename to ion/src/simulator/shared/dummy/serial_number.cpp diff --git a/ion/src/shared/dummy/stack.cpp b/ion/src/simulator/shared/dummy/stack.cpp similarity index 100% rename from ion/src/shared/dummy/stack.cpp rename to ion/src/simulator/shared/dummy/stack.cpp diff --git a/ion/src/shared/dummy/usb.cpp b/ion/src/simulator/shared/dummy/usb.cpp similarity index 100% rename from ion/src/shared/dummy/usb.cpp rename to ion/src/simulator/shared/dummy/usb.cpp diff --git a/ion/src/simulator/shared/events_stdin.cpp b/ion/src/simulator/shared/events_stdin.cpp index 4aaa96093..053118b23 100644 --- a/ion/src/simulator/shared/events_stdin.cpp +++ b/ion/src/simulator/shared/events_stdin.cpp @@ -34,7 +34,7 @@ Event getPlatformEvent() { char filename[32]; sprintf(filename, "event%d.png", sEventCount); Ion::Simulator::Framebuffer::writeToFile(filename); -#if DEBUG +#ifndef NDEBUG printf("Event %d is %s\n", sEventCount, event.name()); #endif } diff --git a/ion/src/simulator/shared/main_headless.cpp b/ion/src/simulator/shared/main_headless.cpp index 0f1fee2de..15cf095d6 100644 --- a/ion/src/simulator/shared/main_headless.cpp +++ b/ion/src/simulator/shared/main_headless.cpp @@ -14,10 +14,10 @@ #endif constexpr int kHeapSize = 131072; -#if DEBUG -constexpr int kStackSize = 32768*2; // In DEBUG mode, we increase the stack to be able to pass the tests -#else +#ifdef NDEBUG constexpr int kStackSize = 32768; +#else +constexpr int kStackSize = 32768*2; // In DEBUG mode, we increase the stack to be able to pass the tests #endif char heap[kHeapSize]; diff --git a/ion/src/simulator/shared/main_sdl.cpp b/ion/src/simulator/shared/main_sdl.cpp index 014d452e9..493f542d2 100644 --- a/ion/src/simulator/shared/main_sdl.cpp +++ b/ion/src/simulator/shared/main_sdl.cpp @@ -2,6 +2,7 @@ #include "display.h" #include "platform.h" #include "layout.h" +#include "random.h" #include #include @@ -79,6 +80,8 @@ void init() { return; } + Random::init(); + uint32_t sdl_window_args = SDL_WINDOW_ALLOW_HIGHDPI | (argument_unresizable ? 0 : SDL_WINDOW_RESIZABLE); if (argument_fullscreen) { diff --git a/ion/src/shared/power.cpp b/ion/src/simulator/shared/power.cpp similarity index 100% rename from ion/src/shared/power.cpp rename to ion/src/simulator/shared/power.cpp diff --git a/ion/src/shared/random.cpp b/ion/src/simulator/shared/random.cpp similarity index 75% rename from ion/src/shared/random.cpp rename to ion/src/simulator/shared/random.cpp index 4f32f8186..615a92c8b 100644 --- a/ion/src/shared/random.cpp +++ b/ion/src/simulator/shared/random.cpp @@ -1,5 +1,11 @@ -#include +#include "random.h" #include +#include + +void Ion::Simulator::Random::init() { + // Set the seed for random using the current time + srand(time(NULL)); +} uint32_t Ion::random() { /* rand() returns a pseudo-random integral number in the range between 0 and diff --git a/ion/src/simulator/shared/random.h b/ion/src/simulator/shared/random.h new file mode 100644 index 000000000..d7c4ac8b1 --- /dev/null +++ b/ion/src/simulator/shared/random.h @@ -0,0 +1,16 @@ +#ifndef ION_SIMULATOR_RANDOM_H +#define ION_SIMULATOR_RANDOM_H + +#include + +namespace Ion { +namespace Simulator { +namespace Random { + +void init(); + +} +} +} + +#endif diff --git a/ion/src/shared/timing.cpp b/ion/src/simulator/shared/timing.cpp similarity index 100% rename from ion/src/shared/timing.cpp rename to ion/src/simulator/shared/timing.cpp diff --git a/ion/test/events.cpp b/ion/test/events.cpp index d7082936c..0c3fd3298 100644 --- a/ion/test/events.cpp +++ b/ion/test/events.cpp @@ -8,15 +8,19 @@ using namespace Ion::Events; QUIZ_CASE(ion_events_from_keyboard) { /* Ensure all events generated from the keyboard are properly defined */ for (Key k : ValidKeys) { - quiz_assert(Event(k, false, false).isDefined()); - quiz_assert(Event(k, true, false).isDefined()); - quiz_assert(Event(k, false, true).isDefined()); - quiz_assert(Event(k, true, true).isDefined()); + quiz_assert(Event(k, false, false, false).isDefined()); + quiz_assert(Event(k, true, false, false).isDefined()); + quiz_assert(Event(k, false, true, false).isDefined()); + quiz_assert(Event(k, true, true, false).isDefined()); + quiz_assert(Event(k, false, true, true).isDefined()); + quiz_assert(Event(k, true, true, true).isDefined()); } // Test some fallbacks - quiz_assert(Event(Key::EXE, false, false) == EXE); - quiz_assert(Event(Key::EXE, true, false) == EXE); - quiz_assert(Event(Key::EXE, false, true) == EXE); - quiz_assert(Event(Key::EXE, true, true) == EXE); + quiz_assert(Event(Key::EXE, false, false, false) == EXE); + quiz_assert(Event(Key::EXE, true, false, false) == EXE); + quiz_assert(Event(Key::EXE, false, true, false) == EXE); + quiz_assert(Event(Key::EXE, true, true, false) == EXE); + quiz_assert(Event(Key::EXE, false, true, true) == EXE); + quiz_assert(Event(Key::EXE, true, true, true) == EXE); } diff --git a/kandinsky/src/rect.cpp b/kandinsky/src/rect.cpp index afad1fe48..f99a09076 100644 --- a/kandinsky/src/rect.cpp +++ b/kandinsky/src/rect.cpp @@ -1,7 +1,5 @@ #include - -static inline KDCoordinate minCoordinate(KDCoordinate x, KDCoordinate y) { return x < y ? x : y; } -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } +#include KDRect::KDRect(KDPoint p, KDSize s) : m_x(p.x()), m_y(p.y()), @@ -38,10 +36,10 @@ KDRect KDRect::intersectedWith(const KDRect & other) const { return KDRectZero; } - KDCoordinate intersectionLeft = maxCoordinate(left(), other.left()); - KDCoordinate intersectionRight = minCoordinate(right(), other.right()); - KDCoordinate intersectionTop = maxCoordinate(top(), other.top()); - KDCoordinate intersectionBottom = minCoordinate(bottom(), other.bottom()); + KDCoordinate intersectionLeft = std::max(left(), other.left()); + KDCoordinate intersectionRight = std::min(right(), other.right()); + KDCoordinate intersectionTop = std::max(top(), other.top()); + KDCoordinate intersectionBottom = std::min(bottom(), other.bottom()); return KDRect( intersectionLeft, @@ -57,8 +55,8 @@ void computeUnionBound(KDCoordinate size1, KDCoordinate size2, { if (size1 != 0) { if (size2 != 0) { - *outputMin = minCoordinate(min1, min2); - *outputMax = maxCoordinate(max1, max2); + *outputMin = std::min(min1, min2); + *outputMax = std::max(max1, max2); } else { *outputMin = min1; *outputMax = max1; diff --git a/liba/Makefile b/liba/Makefile index 31de8ce6f..676fa88d0 100644 --- a/liba/Makefile +++ b/liba/Makefile @@ -57,6 +57,7 @@ liba_src += $(addprefix liba/src/external/openbsd/, \ s_copysignf.c \ s_cosf.c \ s_erf.c \ + s_erff.c \ s_expm1f.o\ s_fabsf.c \ s_fmaxf.c \ @@ -65,6 +66,7 @@ liba_src += $(addprefix liba/src/external/openbsd/, \ s_frexp.c \ s_log1pf.c \ s_logb.c \ + s_logbf.c \ s_modf.c \ s_modff.c \ s_rint.c \ diff --git a/liba/include/assert.h b/liba/include/assert.h index e9d717ab9..ccbf4d8a3 100644 --- a/liba/include/assert.h +++ b/liba/include/assert.h @@ -3,10 +3,10 @@ #include "private/macros.h" -#if DEBUG -#define assert(e) ((void) ((e) ? ((void)0) : __assert(#e, __FILE__, __LINE__))) -#else +#ifdef NDEBUG #define assert(e) ((void)0) +#else +#define assert(e) ((void) ((e) ? ((void)0) : __assert(#e, __FILE__, __LINE__))) #endif LIBA_BEGIN_DECLS diff --git a/liba/include/bridge/string.h b/liba/include/bridge/string.h index bf8417f87..d5eda3946 100644 --- a/liba/include/bridge/string.h +++ b/liba/include/bridge/string.h @@ -8,6 +8,7 @@ LIBA_BEGIN_DECLS #if (__GLIBC__ || __MINGW32__) +size_t strlcat(char * dst, const char * src, size_t dstSize); size_t strlcpy(char * dst, const char * src, size_t len); #endif diff --git a/liba/include/stdint.h b/liba/include/stdint.h index 1b6397153..1096e5ab1 100644 --- a/liba/include/stdint.h +++ b/liba/include/stdint.h @@ -26,6 +26,7 @@ typedef int64_t int_fast64_t; typedef uint8_t uint_least8_t; +#define UINT8_MAX 0xff #define UINT16_MAX 0xffff #define INT16_MAX 0x7fff diff --git a/liba/src/external/openbsd/s_erff.c b/liba/src/external/openbsd/s_erff.c new file mode 100644 index 000000000..f94e2d8e0 --- /dev/null +++ b/liba/src/external/openbsd/s_erff.c @@ -0,0 +1,206 @@ +/* s_erff.c -- float version of s_erf.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "math.h" +#include "math_private.h" + +static const float +tiny = 1e-30, +half= 5.0000000000e-01, /* 0x3F000000 */ +one = 1.0000000000e+00, /* 0x3F800000 */ +two = 2.0000000000e+00, /* 0x40000000 */ + /* c = (subfloat)0.84506291151 */ +erx = 8.4506291151e-01, /* 0x3f58560b */ +/* + * Coefficients for approximation to erf on [0,0.84375] + */ +efx = 1.2837916613e-01, /* 0x3e0375d4 */ +efx8= 1.0270333290e+00, /* 0x3f8375d4 */ +pp0 = 1.2837916613e-01, /* 0x3e0375d4 */ +pp1 = -3.2504209876e-01, /* 0xbea66beb */ +pp2 = -2.8481749818e-02, /* 0xbce9528f */ +pp3 = -5.7702702470e-03, /* 0xbbbd1489 */ +pp4 = -2.3763017452e-05, /* 0xb7c756b1 */ +qq1 = 3.9791721106e-01, /* 0x3ecbbbce */ +qq2 = 6.5022252500e-02, /* 0x3d852a63 */ +qq3 = 5.0813062117e-03, /* 0x3ba68116 */ +qq4 = 1.3249473704e-04, /* 0x390aee49 */ +qq5 = -3.9602282413e-06, /* 0xb684e21a */ +/* + * Coefficients for approximation to erf in [0.84375,1.25] + */ +pa0 = -2.3621185683e-03, /* 0xbb1acdc6 */ +pa1 = 4.1485610604e-01, /* 0x3ed46805 */ +pa2 = -3.7220788002e-01, /* 0xbebe9208 */ +pa3 = 3.1834661961e-01, /* 0x3ea2fe54 */ +pa4 = -1.1089469492e-01, /* 0xbde31cc2 */ +pa5 = 3.5478305072e-02, /* 0x3d1151b3 */ +pa6 = -2.1663755178e-03, /* 0xbb0df9c0 */ +qa1 = 1.0642088205e-01, /* 0x3dd9f331 */ +qa2 = 5.4039794207e-01, /* 0x3f0a5785 */ +qa3 = 7.1828655899e-02, /* 0x3d931ae7 */ +qa4 = 1.2617121637e-01, /* 0x3e013307 */ +qa5 = 1.3637083583e-02, /* 0x3c5f6e13 */ +qa6 = 1.1984500103e-02, /* 0x3c445aa3 */ +/* + * Coefficients for approximation to erfc in [1.25,1/0.35] + */ +ra0 = -9.8649440333e-03, /* 0xbc21a093 */ +ra1 = -6.9385856390e-01, /* 0xbf31a0b7 */ +ra2 = -1.0558626175e+01, /* 0xc128f022 */ +ra3 = -6.2375331879e+01, /* 0xc2798057 */ +ra4 = -1.6239666748e+02, /* 0xc322658c */ +ra5 = -1.8460508728e+02, /* 0xc3389ae7 */ +ra6 = -8.1287437439e+01, /* 0xc2a2932b */ +ra7 = -9.8143291473e+00, /* 0xc11d077e */ +sa1 = 1.9651271820e+01, /* 0x419d35ce */ +sa2 = 1.3765776062e+02, /* 0x4309a863 */ +sa3 = 4.3456588745e+02, /* 0x43d9486f */ +sa4 = 6.4538726807e+02, /* 0x442158c9 */ +sa5 = 4.2900814819e+02, /* 0x43d6810b */ +sa6 = 1.0863500214e+02, /* 0x42d9451f */ +sa7 = 6.5702495575e+00, /* 0x40d23f7c */ +sa8 = -6.0424413532e-02, /* 0xbd777f97 */ +/* + * Coefficients for approximation to erfc in [1/.35,28] + */ +rb0 = -9.8649431020e-03, /* 0xbc21a092 */ +rb1 = -7.9928326607e-01, /* 0xbf4c9dd4 */ +rb2 = -1.7757955551e+01, /* 0xc18e104b */ +rb3 = -1.6063638306e+02, /* 0xc320a2ea */ +rb4 = -6.3756646729e+02, /* 0xc41f6441 */ +rb5 = -1.0250950928e+03, /* 0xc480230b */ +rb6 = -4.8351919556e+02, /* 0xc3f1c275 */ +sb1 = 3.0338060379e+01, /* 0x41f2b459 */ +sb2 = 3.2579251099e+02, /* 0x43a2e571 */ +sb3 = 1.5367296143e+03, /* 0x44c01759 */ +sb4 = 3.1998581543e+03, /* 0x4547fdbb */ +sb5 = 2.5530502930e+03, /* 0x451f90ce */ +sb6 = 4.7452853394e+02, /* 0x43ed43a7 */ +sb7 = -2.2440952301e+01; /* 0xc1b38712 */ + +float +erff(float x) +{ + int32_t hx,ix,i; + float R,S,P,Q,s,y,z,r; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7f800000) { /* erf(nan)=nan */ + i = ((u_int32_t)hx>>31)<<1; + return (float)(1-i)+one/x; /* erf(+-inf)=+-1 */ + } + + if(ix < 0x3f580000) { /* |x|<0.84375 */ + if(ix < 0x31800000) { /* |x|<2**-28 */ + if (ix < 0x04000000) + /*avoid underflow */ + return (float)0.125*((float)8.0*x+efx8*x); + return x + efx*x; + } + z = x*x; + r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); + s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); + y = r/s; + return x + x*y; + } + if(ix < 0x3fa00000) { /* 0.84375 <= |x| < 1.25 */ + s = fabsf(x)-one; + P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); + Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); + if(hx>=0) return erx + P/Q; else return -erx - P/Q; + } + if (ix >= 0x40c00000) { /* inf>|x|>=6 */ + if(hx>=0) return one-tiny; else return tiny-one; + } + x = fabsf(x); + s = one/(x*x); + if(ix< 0x4036DB6E) { /* |x| < 1/0.35 */ + R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( + ra5+s*(ra6+s*ra7)))))); + S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( + sa5+s*(sa6+s*(sa7+s*sa8))))))); + } else { /* |x| >= 1/0.35 */ + R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( + rb5+s*rb6))))); + S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( + sb5+s*(sb6+s*sb7)))))); + } + GET_FLOAT_WORD(ix,x); + SET_FLOAT_WORD(z,ix&0xfffff000); + r = expf(-z*z-(float)0.5625)*expf((z-x)*(z+x)+R/S); + if(hx>=0) return one-r/x; else return r/x-one; +} + +float +erfcf(float x) +{ + int32_t hx,ix; + float R,S,P,Q,s,y,z,r; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7f800000) { /* erfc(nan)=nan */ + /* erfc(+-inf)=0,2 */ + return (float)(((u_int32_t)hx>>31)<<1)+one/x; + } + + if(ix < 0x3f580000) { /* |x|<0.84375 */ + if(ix < 0x23800000) /* |x|<2**-56 */ + return one-x; + z = x*x; + r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); + s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); + y = r/s; + if(hx < 0x3e800000) { /* x<1/4 */ + return one-(x+x*y); + } else { + r = x*y; + r += (x-half); + return half - r ; + } + } + if(ix < 0x3fa00000) { /* 0.84375 <= |x| < 1.25 */ + s = fabsf(x)-one; + P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); + Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); + if(hx>=0) { + z = one-erx; return z - P/Q; + } else { + z = erx+P/Q; return one+z; + } + } + if (ix < 0x41e00000) { /* |x|<28 */ + x = fabsf(x); + s = one/(x*x); + if(ix< 0x4036DB6D) { /* |x| < 1/.35 ~ 2.857143*/ + R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( + ra5+s*(ra6+s*ra7)))))); + S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( + sa5+s*(sa6+s*(sa7+s*sa8))))))); + } else { /* |x| >= 1/.35 ~ 2.857143 */ + if(hx<0&&ix>=0x40c00000) return two-tiny;/* x < -6 */ + R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( + rb5+s*rb6))))); + S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( + sb5+s*(sb6+s*sb7)))))); + } + GET_FLOAT_WORD(ix,x); + SET_FLOAT_WORD(z,ix&0xfffff000); + r = expf(-z*z-(float)0.5625) * expf((z-x)*(z+x)+R/S); + if(hx>0) return r/x; else return two-r/x; + } else { + if(hx>0) return tiny*tiny; else return two-tiny; + } +} diff --git a/liba/src/external/openbsd/s_logbf.c b/liba/src/external/openbsd/s_logbf.c new file mode 100644 index 000000000..bed408efa --- /dev/null +++ b/liba/src/external/openbsd/s_logbf.c @@ -0,0 +1,31 @@ +/* s_logbf.c -- float version of s_logb.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "math.h" +#include "math_private.h" + +float +logbf(float x) +{ + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; /* high |x| */ + if(ix==0) return (float)-1.0/fabsf(x); + if(ix>=0x7f800000) return x*x; + if((ix>>=23)==0) /* IEEE 754 logb */ + return -126.0; + else + return (float) (ix-127); +} diff --git a/libaxx/include/algorithm b/libaxx/include/algorithm new file mode 100644 index 000000000..b2c7073c4 --- /dev/null +++ b/libaxx/include/algorithm @@ -0,0 +1,18 @@ +#ifndef LIBAXX_ALGORITHM +#define LIBAXX_ALGORITHM + +namespace std { + +template +inline const T & min(const T & a, const T & b ) { + return (b < a) ? b : a; +} + +template +inline const T & max(const T & a, const T & b ) { + return (b > a) ? b : a; +} + +} + +#endif diff --git a/libaxx/include/cmath b/libaxx/include/cmath index 6a3e3894e..9fdad6b7a 100644 --- a/libaxx/include/cmath +++ b/libaxx/include/cmath @@ -114,6 +114,8 @@ inline constexpr float ceil(float x) { return __builtin_ceilf(x); } inline constexpr float copysign(float x, float y) { return __builtin_copysignf(x, y); } inline constexpr float cos(float x) { return __builtin_cosf(x); } inline constexpr float cosh(float x) { return __builtin_coshf(x); } +inline constexpr float erf(float x) { return __builtin_erff(x); } +inline constexpr float erfc(float x) { return __builtin_erfcf(x); } inline constexpr float exp(float x) { return __builtin_expf(x); } inline constexpr float expm1(float x) { return __builtin_expm1f(x); } inline constexpr float fabs(float x) { return __builtin_fabsf(x); } @@ -121,12 +123,14 @@ inline constexpr float floor(float x) { return __builtin_floorf(x); } inline constexpr float fmax(float x, float y) { return __builtin_fmaxf(x, y); } inline constexpr float fmod(float x, float y) { return __builtin_fmodf(x, y); } inline constexpr float frexp(float x, int *exp) { return __builtin_frexpf(x, exp); } +inline constexpr float hypot(float x, float y) { return __builtin_hypotf(x, y); } inline constexpr float ldexp(float x, int exp) { return __builtin_ldexpf(x, exp); } inline constexpr float lgamma(float x) { return __builtin_lgammaf(x); } inline constexpr float lgamma_r(float x, int *signgamp) { return __builtin_lgammaf_r(x, signgamp); } +inline constexpr float log(float x) { return __builtin_logf(x); } inline constexpr float log1p(float x) { return __builtin_log1pf(x); } inline constexpr float log10(float x) { return __builtin_log10f(x); } -inline constexpr float log(float x) { return __builtin_logf(x); } +inline constexpr float logb(float x) { return __builtin_logbf(x); } inline constexpr float modf(float x, float *iptr) { return __builtin_modff(x, iptr); } inline constexpr float nanf(const char *tagp) { return __builtin_nanf(tagp); } inline constexpr float nearbyint(float x) { return __builtin_nearbyintf(x); } diff --git a/libaxx/include/initializer_list b/libaxx/include/initializer_list new file mode 100644 index 000000000..aadee9cbb --- /dev/null +++ b/libaxx/include/initializer_list @@ -0,0 +1,35 @@ +#ifndef LIBAXX_INITIALIZER_LIST +#define LIBAXX_INITIALIZER_LIST + +#include + +namespace std { + +template +class initializer_list { +public: + initializer_list() noexcept : m_begin(nullptr), m_size(0) {} + const T * begin() const noexcept { return m_begin; } + const T * end() const noexcept { return m_begin + m_size; } +private: + initializer_list(const T * begin, size_t size) noexcept + : m_begin(begin), + m_size(size) + {} + const T * m_begin; + size_t m_size; +}; + +template +inline const T * begin(initializer_list il) noexcept { + return il.begin(); +} + +template +inline const T * end(initializer_list il) noexcept { + return il.end(); +} + +} + +#endif diff --git a/poincare/include/poincare/absolute_value.h b/poincare/include/poincare/absolute_value.h index 411259dd8..e0a12aa6a 100644 --- a/poincare/include/poincare/absolute_value.h +++ b/poincare/include/poincare/absolute_value.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(AbsoluteValueNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "AbsoluteValue"; } #endif @@ -48,7 +48,7 @@ class AbsoluteValue final : public Expression { friend class AbsoluteValueNode; public: AbsoluteValue(const AbsoluteValueNode * n) : Expression(n) {} - static AbsoluteValue Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static AbsoluteValue Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("abs", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/absolute_value_layout.h b/poincare/include/poincare/absolute_value_layout.h index 0aa42cb75..d1cab825d 100644 --- a/poincare/include/poincare/absolute_value_layout.h +++ b/poincare/include/poincare/absolute_value_layout.h @@ -22,7 +22,7 @@ public: // TreeNode size_t size() const override { return sizeof(AbsoluteValueLayoutNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "AbsoluteValueLayout"; } #endif @@ -36,7 +36,7 @@ private: class AbsoluteValueLayout final : public Layout { public: - static AbsoluteValueLayout Builder(Layout child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static AbsoluteValueLayout Builder(Layout child) { return TreeHandle::FixedArityBuilder({child}); } AbsoluteValueLayout() = delete; }; diff --git a/poincare/include/poincare/addition.h b/poincare/include/poincare/addition.h index 1cb04f8a8..63971f23f 100644 --- a/poincare/include/poincare/addition.h +++ b/poincare/include/poincare/addition.h @@ -15,7 +15,7 @@ public: // Tree size_t size() const override { return sizeof(AdditionNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Addition"; } #endif @@ -73,10 +73,12 @@ private: class Addition final : public NAryExpression { public: Addition(const AdditionNode * n) : NAryExpression(n) {} - static Addition Builder() { return TreeHandle::NAryBuilder(); } - 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) { return TreeHandle::NAryBuilder(children, numberOfChildren); } + static Addition Builder(const Tuple & children = {}) { + return TreeHandle::NAryBuilder(convert(children)); + } + // TODO: Get rid of these two helper functions + static Addition Builder(Expression e1) { return Addition::Builder({e1}); } + static Addition Builder(Expression e1, Expression e2) { return Addition::Builder({e1, e2}); } // Expression Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); Expression shallowBeautify(ExpressionNode::ReductionContext reductionContext); diff --git a/poincare/include/poincare/arc_cosine.h b/poincare/include/poincare/arc_cosine.h index 8a5d04a76..43bac523f 100644 --- a/poincare/include/poincare/arc_cosine.h +++ b/poincare/include/poincare/arc_cosine.h @@ -14,7 +14,7 @@ public: size_t size() const override { return sizeof(ArcCosineNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "ArcCosine"; } #endif @@ -45,7 +45,7 @@ private: class ArcCosine final : public Expression { public: ArcCosine(const ArcCosineNode * n) : Expression(n) {} - static ArcCosine Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static ArcCosine Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("acos", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/arc_sine.h b/poincare/include/poincare/arc_sine.h index 228c798fc..2747bda13 100644 --- a/poincare/include/poincare/arc_sine.h +++ b/poincare/include/poincare/arc_sine.h @@ -14,7 +14,7 @@ public: size_t size() const override { return sizeof(ArcSineNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "ArcSine"; } #endif @@ -43,7 +43,7 @@ private: class ArcSine final : public Expression { public: ArcSine(const ArcSineNode * n) : Expression(n) {} - static ArcSine Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static ArcSine Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("asin", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/arc_tangent.h b/poincare/include/poincare/arc_tangent.h index 9fa7e1c90..47b6f5638 100644 --- a/poincare/include/poincare/arc_tangent.h +++ b/poincare/include/poincare/arc_tangent.h @@ -14,7 +14,7 @@ public: size_t size() const override { return sizeof(ArcTangentNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "ArcTangent"; } #endif @@ -44,7 +44,7 @@ private: class ArcTangent final : public Expression { public: ArcTangent(const ArcTangentNode * n) : Expression(n) {} - static ArcTangent Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static ArcTangent Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("atan", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/array_builder.h b/poincare/include/poincare/array_builder.h deleted file mode 100644 index ed7b232f1..000000000 --- a/poincare/include/poincare/array_builder.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef POINCARE_ARRAY_BUILDER_H -#define POINCARE_ARRAY_BUILDER_H - - -namespace Poincare { - -template -class ArrayBuilder { -public: - ArrayBuilder(T e1 = T(), T e2 = T(), T e3 = T(), T e4 = T()) : - m_data{e1, e2, e3, e4} - {} - T * array() { return const_cast(m_data); } -private: - T m_data[4]; -}; - -} - -#endif diff --git a/poincare/include/poincare/based_integer.h b/poincare/include/poincare/based_integer.h index 74ee6fb5a..566a334a4 100644 --- a/poincare/include/poincare/based_integer.h +++ b/poincare/include/poincare/based_integer.h @@ -16,7 +16,7 @@ public: // TreeNode size_t size() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Based Integer"; } virtual void logAttributes(std::ostream & stream) const override; diff --git a/poincare/include/poincare/binom_cdf.h b/poincare/include/poincare/binom_cdf.h index 48f491256..832040818 100644 --- a/poincare/include/poincare/binom_cdf.h +++ b/poincare/include/poincare/binom_cdf.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(BinomCDFNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "BinomCDF"; } #endif @@ -37,7 +37,7 @@ private: class BinomCDF final : public BinomialDistributionFunction { public: BinomCDF(const BinomCDFNode * n) : BinomialDistributionFunction(n) {} - static BinomCDF Builder(Expression child0, Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1, child2).array(), 3); } + static BinomCDF Builder(Expression child0, Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder({child0, child1, child2}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("binomcdf", 3, &UntypedBuilderThreeChildren); }; diff --git a/poincare/include/poincare/binom_pdf.h b/poincare/include/poincare/binom_pdf.h index cfd89b6ec..c316e5aed 100644 --- a/poincare/include/poincare/binom_pdf.h +++ b/poincare/include/poincare/binom_pdf.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(BinomPDFNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "BinomPDF"; } #endif @@ -37,7 +37,7 @@ private: class BinomPDF final : public BinomialDistributionFunction { public: BinomPDF(const BinomPDFNode * n) : BinomialDistributionFunction(n) {} - static BinomPDF Builder(Expression child0, Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1, child2).array(), 3); } + static BinomPDF Builder(Expression child0, Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder({child0, child1, child2}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("binompdf", 3, &UntypedBuilderThreeChildren); }; diff --git a/poincare/include/poincare/binomial_coefficient.h b/poincare/include/poincare/binomial_coefficient.h index 0d98aed25..992cf88d0 100644 --- a/poincare/include/poincare/binomial_coefficient.h +++ b/poincare/include/poincare/binomial_coefficient.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(BinomialCoefficientNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "BinomialCoefficient"; } #endif @@ -38,7 +38,7 @@ private: class BinomialCoefficient final : public Expression { public: BinomialCoefficient(const BinomialCoefficientNode * n) : Expression(n) {} - static BinomialCoefficient Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } + static BinomialCoefficient Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder({child0, child1}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("binomial", 2, &UntypedBuilderTwoChildren); // Expression diff --git a/poincare/include/poincare/binomial_coefficient_layout.h b/poincare/include/poincare/binomial_coefficient_layout.h index 210207062..063c4c8ac 100644 --- a/poincare/include/poincare/binomial_coefficient_layout.h +++ b/poincare/include/poincare/binomial_coefficient_layout.h @@ -27,7 +27,7 @@ public: size_t size() const override { return sizeof(BinomialCoefficientLayoutNode); } int numberOfChildren() const override { return 2; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "BinomialCoefficientLayout"; } #endif @@ -46,7 +46,7 @@ private: class BinomialCoefficientLayout final : public Layout { public: - static BinomialCoefficientLayout Builder(Layout child0, Layout child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } + static BinomialCoefficientLayout Builder(Layout child0, Layout child1) { return TreeHandle::FixedArityBuilder({child0, child1}); } BinomialCoefficientLayout() = delete; }; diff --git a/poincare/include/poincare/ceiling.h b/poincare/include/poincare/ceiling.h index 31f5db941..ff1bc5a10 100644 --- a/poincare/include/poincare/ceiling.h +++ b/poincare/include/poincare/ceiling.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(CeilingNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Ceiling"; } #endif @@ -41,7 +41,7 @@ private: class Ceiling final : public Expression { public: Ceiling(const CeilingNode * n) : Expression(n) {} - static Ceiling Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static Ceiling Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("ceil", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/ceiling_layout.h b/poincare/include/poincare/ceiling_layout.h index a0f553aeb..fbb85209e 100644 --- a/poincare/include/poincare/ceiling_layout.h +++ b/poincare/include/poincare/ceiling_layout.h @@ -22,7 +22,7 @@ public: // TreeNode size_t size() const override { return sizeof(CeilingLayoutNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "CeilingLayout"; } #endif @@ -33,7 +33,7 @@ protected: class CeilingLayout final : public Layout { public: - static CeilingLayout Builder(Layout child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static CeilingLayout Builder(Layout child) { return TreeHandle::FixedArityBuilder({child}); } CeilingLayout() = delete; }; diff --git a/poincare/include/poincare/code_point_layout.h b/poincare/include/poincare/code_point_layout.h index d8d4dfbbf..8c5ec928c 100644 --- a/poincare/include/poincare/code_point_layout.h +++ b/poincare/include/poincare/code_point_layout.h @@ -39,7 +39,7 @@ public: size_t size() const override { return sizeof(CodePointLayoutNode); } int numberOfChildren() const override { return 0; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "CodePointLayout"; } virtual void logAttributes(std::ostream & stream) const override { diff --git a/poincare/include/poincare/complex.h b/poincare/include/poincare/complex.h index e8e92690d..5f4aec757 100644 --- a/poincare/include/poincare/complex.h +++ b/poincare/include/poincare/complex.h @@ -17,7 +17,7 @@ public: size_t size() const override { return sizeof(ComplexNode); } int numberOfChildren() const override { return 0; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Complex"; } virtual void logAttributes(std::ostream & stream) const override { diff --git a/poincare/include/poincare/complex_argument.h b/poincare/include/poincare/complex_argument.h index 44b27147a..4264428c6 100644 --- a/poincare/include/poincare/complex_argument.h +++ b/poincare/include/poincare/complex_argument.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(ComplexArgumentNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "ComplexArgument"; } #endif @@ -42,7 +42,7 @@ private: class ComplexArgument final : public Expression { public: ComplexArgument(const ComplexArgumentNode * n) : Expression(n) {} - static ComplexArgument Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static ComplexArgument Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("arg", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/complex_cartesian.h b/poincare/include/poincare/complex_cartesian.h index bc8b61328..f9a71c5fd 100644 --- a/poincare/include/poincare/complex_cartesian.h +++ b/poincare/include/poincare/complex_cartesian.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(ComplexCartesianNode); } int numberOfChildren() const override { return 2; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "ComplexCartesian"; } #endif @@ -44,7 +44,7 @@ public: ComplexCartesian() : Expression() {} ComplexCartesian(const ComplexCartesianNode * node) : Expression(node) {} static ComplexCartesian Builder() { return TreeHandle::FixedArityBuilder(); } - static ComplexCartesian Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } + static ComplexCartesian Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder({child0, child1}); } // Getters Expression real() { return childAtIndex(0); } diff --git a/poincare/include/poincare/condensed_sum_layout.h b/poincare/include/poincare/condensed_sum_layout.h index 6f5bb5e88..e48c3bb11 100644 --- a/poincare/include/poincare/condensed_sum_layout.h +++ b/poincare/include/poincare/condensed_sum_layout.h @@ -36,7 +36,7 @@ public: size_t size() const override { return sizeof(CondensedSumLayoutNode); } int numberOfChildren() const override { return 3; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "CondensedSumLayout"; } #endif @@ -55,7 +55,7 @@ private: class CondensedSumLayout final : public Layout { public: - static CondensedSumLayout Builder(Layout base, Layout subscript, Layout superscript) { return TreeHandle::FixedArityBuilder(ArrayBuilder(base, subscript, superscript).array(), 3); } + static CondensedSumLayout Builder(Layout base, Layout subscript, Layout superscript) { return TreeHandle::FixedArityBuilder({base, subscript, superscript}); } CondensedSumLayout() = delete; }; diff --git a/poincare/include/poincare/confidence_interval.h b/poincare/include/poincare/confidence_interval.h index f9ea855c9..f0d78e2d3 100644 --- a/poincare/include/poincare/confidence_interval.h +++ b/poincare/include/poincare/confidence_interval.h @@ -12,7 +12,7 @@ public: size_t size() const override { return sizeof(ConfidenceIntervalNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "ConfidenceInterval"; } #endif @@ -48,7 +48,7 @@ class ConfidenceInterval : public Expression { friend class SimplePredictionInterval; public: ConfidenceInterval(const ConfidenceIntervalNode * n) : Expression(n) {} - static ConfidenceInterval Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } + static ConfidenceInterval Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder({child0, child1}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("confidence", 2, &UntypedBuilderTwoChildren); // Expression @@ -60,7 +60,7 @@ private: class SimplePredictionInterval final : public ConfidenceInterval { public: SimplePredictionInterval(const SimplePredictionIntervalNode * n) : ConfidenceInterval(n) {} - static SimplePredictionInterval Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } + static SimplePredictionInterval Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder({child0, child1}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("prediction", 2, &UntypedBuilderTwoChildren); }; diff --git a/poincare/include/poincare/conjugate.h b/poincare/include/poincare/conjugate.h index 07434ef90..61b442fc5 100644 --- a/poincare/include/poincare/conjugate.h +++ b/poincare/include/poincare/conjugate.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(ConjugateNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Conjugate"; } #endif @@ -42,7 +42,7 @@ private: class Conjugate final : public Expression { public: Conjugate(const ConjugateNode * n) : Expression(n) {} - static Conjugate Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static Conjugate Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("conj", 1, &UntypedBuilderOneChild);; diff --git a/poincare/include/poincare/conjugate_layout.h b/poincare/include/poincare/conjugate_layout.h index e56187c77..e64a83963 100644 --- a/poincare/include/poincare/conjugate_layout.h +++ b/poincare/include/poincare/conjugate_layout.h @@ -23,7 +23,7 @@ public: size_t size() const override { return sizeof(ConjugateLayoutNode); } int numberOfChildren() const override { return 1; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "ConjugateLayout"; } #endif @@ -43,7 +43,7 @@ private: class ConjugateLayout final : public Layout { public: - static ConjugateLayout Builder(Layout child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static ConjugateLayout Builder(Layout child) { return TreeHandle::FixedArityBuilder({child}); } ConjugateLayout() = delete; }; diff --git a/poincare/include/poincare/constant.h b/poincare/include/poincare/constant.h index 591ca7e2d..59d1a4d48 100644 --- a/poincare/include/poincare/constant.h +++ b/poincare/include/poincare/constant.h @@ -17,7 +17,7 @@ public: // TreeNode int numberOfChildren() const override { return 0; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Constant"; } #endif @@ -43,7 +43,7 @@ public: CodePoint codePoint() const; // Comparison - int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const override; + int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; diff --git a/poincare/include/poincare/cosine.h b/poincare/include/poincare/cosine.h index 9b79621c0..5855d8a9d 100644 --- a/poincare/include/poincare/cosine.h +++ b/poincare/include/poincare/cosine.h @@ -14,7 +14,7 @@ public: size_t size() const override { return sizeof(CosineNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Cosine"; } #endif @@ -46,7 +46,7 @@ private: class Cosine final : public Expression { public: Cosine(const CosineNode * n) : Expression(n) {} - static Cosine Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static Cosine Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("cos", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/decimal.h b/poincare/include/poincare/decimal.h index 60b7e69ba..ee1b0cd5b 100644 --- a/poincare/include/poincare/decimal.h +++ b/poincare/include/poincare/decimal.h @@ -27,7 +27,7 @@ public: // TreeNode size_t size() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Decimal"; } virtual void logAttributes(std::ostream & stream) const override { @@ -56,7 +56,7 @@ public: /* Warning: Decimal(mantissa: 1000, exponent: 3) and Decimal(mantissa: 1, exponent: 3) * are strictly ordered with the SimplificationOrder although they are equal * with the usual math order (1.000E3 == 1E3). */ - int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const override; + int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; diff --git a/poincare/include/poincare/derivative.h b/poincare/include/poincare/derivative.h index 6211e86ce..ad622c73b 100644 --- a/poincare/include/poincare/derivative.h +++ b/poincare/include/poincare/derivative.h @@ -14,7 +14,7 @@ public: size_t size() const override { return sizeof(DerivativeNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Derivative"; } #endif @@ -49,7 +49,7 @@ private: class Derivative final : public ParameteredExpression { public: Derivative(const DerivativeNode * n) : ParameteredExpression(n) {} - static Derivative Builder(Expression child0, Symbol child1, Expression child2) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1, child2).array(), 3); } + static Derivative Builder(Expression child0, Symbol child1, Expression child2) { return TreeHandle::FixedArityBuilder({child0, child1, child2}); } static Expression UntypedBuilder(Expression children); static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("diff", 3, &UntypedBuilder); diff --git a/poincare/include/poincare/determinant.h b/poincare/include/poincare/determinant.h index 8ea361c60..1a1a043e4 100644 --- a/poincare/include/poincare/determinant.h +++ b/poincare/include/poincare/determinant.h @@ -12,7 +12,7 @@ public: size_t size() const override { return sizeof(DeterminantNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Determinant"; } #endif @@ -37,7 +37,7 @@ private: class Determinant final : public Expression { public: Determinant(const DeterminantNode * n) : Expression(n) {} - static Determinant Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static Determinant Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("det", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/division.h b/poincare/include/poincare/division.h index 5c2bb56b2..262f4a418 100644 --- a/poincare/include/poincare/division.h +++ b/poincare/include/poincare/division.h @@ -17,7 +17,7 @@ public: size_t size() const override { return sizeof(DivisionNode); } int numberOfChildren() const override { return 2; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Division"; } #endif @@ -64,7 +64,7 @@ class Division final : public Expression { public: Division(const DivisionNode * n) : Expression(n) {} static Division Builder() { return TreeHandle::FixedArityBuilder(); } - static Division Builder(Expression numerator, Expression denominator) { return TreeHandle::FixedArityBuilder(ArrayBuilder(numerator, denominator).array(), 2); } + static Division Builder(Expression numerator, Expression denominator) { return TreeHandle::FixedArityBuilder({numerator, denominator}); } Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; diff --git a/poincare/include/poincare/division_quotient.h b/poincare/include/poincare/division_quotient.h index 654059c1b..e55fcec65 100644 --- a/poincare/include/poincare/division_quotient.h +++ b/poincare/include/poincare/division_quotient.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(DivisionQuotientNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "DivisionQuotient"; } #endif @@ -40,7 +40,7 @@ private: class DivisionQuotient final : public Expression { public: DivisionQuotient(const DivisionQuotientNode * n) : Expression(n) {} - static DivisionQuotient Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } + static DivisionQuotient Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder({child0, child1}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("quo", 2, &UntypedBuilderTwoChildren); // Expression diff --git a/poincare/include/poincare/division_remainder.h b/poincare/include/poincare/division_remainder.h index 5fcfc7271..3794c370d 100644 --- a/poincare/include/poincare/division_remainder.h +++ b/poincare/include/poincare/division_remainder.h @@ -14,7 +14,7 @@ public: size_t size() const override { return sizeof(DivisionRemainderNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "DivisionRemainder"; } #endif @@ -42,7 +42,7 @@ private: class DivisionRemainder final : public Expression { public: DivisionRemainder(const DivisionRemainderNode * n) : Expression(n) {} - static DivisionRemainder Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } + static DivisionRemainder Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder({child0, child1}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("rem", 2, &UntypedBuilderTwoChildren); // Expression diff --git a/poincare/include/poincare/empty_expression.h b/poincare/include/poincare/empty_expression.h index eb2824fb8..3814f3e91 100644 --- a/poincare/include/poincare/empty_expression.h +++ b/poincare/include/poincare/empty_expression.h @@ -14,7 +14,7 @@ public: size_t size() const override { return sizeof(EmptyExpressionNode); } int numberOfChildren() const override { return 0; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "EmptyExpression"; } #endif diff --git a/poincare/include/poincare/empty_layout.h b/poincare/include/poincare/empty_layout.h index 8361c09b5..14cd3bb15 100644 --- a/poincare/include/poincare/empty_layout.h +++ b/poincare/include/poincare/empty_layout.h @@ -42,7 +42,7 @@ public: size_t size() const override { return sizeof(EmptyLayoutNode); } int numberOfChildren() const override { return 0; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "EmptyLayout"; } #endif diff --git a/poincare/include/poincare/equal.h b/poincare/include/poincare/equal.h index fd40f1bfe..6826f35ab 100644 --- a/poincare/include/poincare/equal.h +++ b/poincare/include/poincare/equal.h @@ -12,7 +12,7 @@ public: size_t size() const override { return sizeof(EqualNode); } int numberOfChildren() const override { return 2; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Equal"; } #endif @@ -36,7 +36,7 @@ private: class Equal final : public Expression { public: Equal(const EqualNode * n) : Expression(n) {} - static Equal Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } + static Equal Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder({child0, 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/expression.h b/poincare/include/poincare/expression.h index 86e8e0b9b..c8aa3cc10 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -1,7 +1,6 @@ #ifndef POINCARE_EXPRESSION_REFERENCE_H #define POINCARE_EXPRESSION_REFERENCE_H -#include #include #include #include @@ -217,6 +216,9 @@ public: * same structures and all their nodes have same types and values (ie, * sqrt(pi^2) is NOT identical to pi). */ bool isIdenticalTo(const Expression e) const; + /* isIdenticalToWithoutParentheses behaves as isIdenticalTo, but without + * taking into account parentheses: e^(0) is identical to e^0. */ + bool isIdenticalToWithoutParentheses(const Expression e) const; static bool ParsedExpressionsAreEqual(const char * e0, const char * e1, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); /* Layout Helper */ @@ -286,6 +288,9 @@ public: static void Tidy() { sSymbolReplacementsCountLock = false; } + /* Tuple */ + typedef std::initializer_list Tuple; + protected: static bool SimplificationHasBeenInterrupted(); Expression(const ExpressionNode * n) : TreeHandle(n) {} @@ -328,6 +333,12 @@ protected: return *reinterpret_cast(const_cast(this)); } + static_assert(sizeof(TreeHandle::Tuple) == sizeof(Tuple), "Size mismatch"); + static const TreeHandle::Tuple & convert(const Tuple & l) { + assert(sizeof(TreeHandle) == sizeof(Expression)); + return reinterpret_cast(l); + } + /* Reference */ ExpressionNode * node() const { assert(identifier() != TreeNode::NoNodeIdentifier || !TreeHandle::node()->isGhost()); diff --git a/poincare/include/poincare/expression_node.h b/poincare/include/poincare/expression_node.h index 26acc69e1..21b19004d 100644 --- a/poincare/include/poincare/expression_node.h +++ b/poincare/include/poincare/expression_node.h @@ -191,15 +191,15 @@ public: * together (ie Pi, 2*Pi). * Because SimplificationOrder is a recursive call, we sometimes enable its * interruption to avoid freezing in the simplification process. */ - static int SimplificationOrder(const ExpressionNode * e1, const ExpressionNode * e2, bool ascending, bool canBeInterrupted = false); + static int SimplificationOrder(const ExpressionNode * e1, const ExpressionNode * e2, bool ascending, bool canBeInterrupted = false, bool ignoreParentheses = false); /* In the simplification order, most expressions are compared by only * comparing their types. However hierarchical expressions of same type would * compare their operands and thus need to reimplement * simplificationOrderSameType. Besides, operations that can be simplified * (ie +, *, ^, !) have specific rules to group like terms together and thus * reimplement simplificationOrderGreaterType. */ - virtual int simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const { return ascending ? -1 : 1; } - virtual int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const; + virtual int simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const { return ascending ? -1 : 1; } + virtual int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const; /* Layout Helper */ virtual Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const = 0; diff --git a/poincare/include/poincare/factor.h b/poincare/include/poincare/factor.h index 7f8dc7668..39e1ce4d5 100644 --- a/poincare/include/poincare/factor.h +++ b/poincare/include/poincare/factor.h @@ -14,7 +14,7 @@ public: size_t size() const override { return sizeof(FactorNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Factor"; } #endif @@ -39,7 +39,7 @@ private: class Factor final : public Expression { public: Factor(const FactorNode * n) : Expression(n) {} - static Factor Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static Factor Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("factor", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/factorial.h b/poincare/include/poincare/factorial.h index 0a06b71f0..212a94c57 100644 --- a/poincare/include/poincare/factorial.h +++ b/poincare/include/poincare/factorial.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(FactorialNode); } int numberOfChildren() const override { return 1; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Factorial"; } #endif @@ -52,7 +52,7 @@ private: class Factorial final : public Expression { public: Factorial(const FactorialNode * n) : Expression(n) {} - static Factorial Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static Factorial Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); private: diff --git a/poincare/include/poincare/float.h b/poincare/include/poincare/float.h index 8c6db2d73..2a1b032bb 100644 --- a/poincare/include/poincare/float.h +++ b/poincare/include/poincare/float.h @@ -27,7 +27,7 @@ public: // TreeNode size_t size() const override { return sizeof(FloatNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Float"; } virtual void logAttributes(std::ostream & stream) const override { @@ -39,7 +39,7 @@ public: Type type() const override { return Type::Float; } Sign sign(Context * context) const override { return m_value < 0 ? Sign::Negative : Sign::Positive; } Expression setSign(Sign s, ReductionContext reductionContext) override; - int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const override; + int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override; // Layout int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; diff --git a/poincare/include/poincare/floor.h b/poincare/include/poincare/floor.h index e2462efff..65115adaa 100644 --- a/poincare/include/poincare/floor.h +++ b/poincare/include/poincare/floor.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(FloorNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Floor"; } #endif @@ -42,7 +42,7 @@ private: class Floor final : public Expression { public: Floor(const FloorNode * n) : Expression(n) {} - static Floor Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static Floor Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("floor", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/floor_layout.h b/poincare/include/poincare/floor_layout.h index f3f0cab60..9870dfad0 100644 --- a/poincare/include/poincare/floor_layout.h +++ b/poincare/include/poincare/floor_layout.h @@ -22,7 +22,7 @@ public: // TreeNode size_t size() const override { return sizeof(FloorLayoutNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "FloorLayout"; } #endif @@ -33,7 +33,7 @@ protected: class FloorLayout final : public Layout { public: - static FloorLayout Builder(Layout child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static FloorLayout Builder(Layout child) { return TreeHandle::FixedArityBuilder({child}); } FloorLayout() = delete; }; diff --git a/poincare/include/poincare/frac_part.h b/poincare/include/poincare/frac_part.h index d25baf0b7..0158bb9e7 100644 --- a/poincare/include/poincare/frac_part.h +++ b/poincare/include/poincare/frac_part.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(FracPartNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "FracPart"; } #endif @@ -45,7 +45,7 @@ private: class FracPart final : public Expression { public: FracPart(const FracPartNode * n) : Expression(n) {} - static FracPart Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static FracPart Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("frac", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/fraction_layout.h b/poincare/include/poincare/fraction_layout.h index 68b7cbb12..99a054aa2 100644 --- a/poincare/include/poincare/fraction_layout.h +++ b/poincare/include/poincare/fraction_layout.h @@ -39,7 +39,7 @@ public: size_t size() const override { return sizeof(FractionLayoutNode); } int numberOfChildren() const override { return 2; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "FractionLayout"; } #endif @@ -61,7 +61,7 @@ private: class FractionLayout final : public Layout { public: - static FractionLayout Builder(Layout child0, Layout child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } + static FractionLayout Builder(Layout child0, Layout child1) { return TreeHandle::FixedArityBuilder({child0, child1}); } FractionLayout() = delete; }; diff --git a/poincare/include/poincare/function.h b/poincare/include/poincare/function.h index 999321f8d..bb2d2f92c 100644 --- a/poincare/include/poincare/function.h +++ b/poincare/include/poincare/function.h @@ -16,7 +16,7 @@ public: // TreeNode int numberOfChildren() const override { return 1; } //TODO allow any number of children? Needs templating #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Function"; } #endif diff --git a/poincare/include/poincare/ghost_node.h b/poincare/include/poincare/ghost_node.h index fd3f491bb..69ca981d6 100644 --- a/poincare/include/poincare/ghost_node.h +++ b/poincare/include/poincare/ghost_node.h @@ -11,7 +11,7 @@ public: int numberOfChildren() const override { return 0; } size_t size() const override { return sizeof(GhostNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Ghost"; } #endif diff --git a/poincare/include/poincare/great_common_divisor.h b/poincare/include/poincare/great_common_divisor.h index 66a86ca97..96429d951 100644 --- a/poincare/include/poincare/great_common_divisor.h +++ b/poincare/include/poincare/great_common_divisor.h @@ -12,7 +12,7 @@ public: size_t size() const override { return sizeof(GreatCommonDivisorNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "GreatCommonDivisor"; } #endif @@ -37,7 +37,7 @@ private: class GreatCommonDivisor final : public Expression { public: GreatCommonDivisor(const GreatCommonDivisorNode * n) : Expression(n) {} - static GreatCommonDivisor Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } + static GreatCommonDivisor Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder({child0, child1}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("gcd", 2, &UntypedBuilderTwoChildren); // Expression diff --git a/poincare/include/poincare/grid_layout.h b/poincare/include/poincare/grid_layout.h index 8a7534386..9f5ec3296 100644 --- a/poincare/include/poincare/grid_layout.h +++ b/poincare/include/poincare/grid_layout.h @@ -52,7 +52,7 @@ public: m_numberOfColumns = 0; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "GridLayout"; } #endif diff --git a/poincare/include/poincare/horizontal_layout.h b/poincare/include/poincare/horizontal_layout.h index 7c9b5ae2c..22555f727 100644 --- a/poincare/include/poincare/horizontal_layout.h +++ b/poincare/include/poincare/horizontal_layout.h @@ -47,7 +47,7 @@ public: } void eraseNumberOfChildren() override { m_numberOfChildren = 0; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "HorizontalLayout"; } #endif @@ -75,12 +75,14 @@ class HorizontalLayout final : public Layout { public: // Constructors HorizontalLayout(HorizontalLayoutNode * n) : Layout(n) {} - static HorizontalLayout Builder() { return TreeHandle::NAryBuilder(); } - 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); } - static HorizontalLayout Builder(Layout l1, Layout l2, Layout l3, Layout l4) { return HorizontalLayout::Builder(ArrayBuilder(l1, l2, l3, l4).array(), 4); } - static HorizontalLayout Builder(Layout * children, size_t numberOfChildren) { return TreeHandle::NAryBuilder(static_cast(children), numberOfChildren); } + + // FIXME: use Layout instead of TreeHandle + static HorizontalLayout Builder(std::initializer_list children = {}) { return TreeHandle::NAryBuilder(children); } + // TODO: Get rid of those helpers + static HorizontalLayout Builder(Layout l) { return Builder({l}); } + static HorizontalLayout Builder(Layout l1, Layout l2) { return Builder({l1, l2}); } + static HorizontalLayout Builder(Layout l1, Layout l2, Layout l3) { return Builder({l1, l2, l3}); } + static HorizontalLayout Builder(Layout l1, Layout l2, Layout l3, Layout l4) { return Builder({l1, l2, l3, l4}); } void addChildAtIndex(Layout l, int index, int currentNumberOfChildren, LayoutCursor * cursor, bool removeEmptyChildren = false); // Remove puts a child at the end of the pool diff --git a/poincare/include/poincare/hyperbolic_arc_cosine.h b/poincare/include/poincare/hyperbolic_arc_cosine.h index c49ca9617..ac0a6aee8 100644 --- a/poincare/include/poincare/hyperbolic_arc_cosine.h +++ b/poincare/include/poincare/hyperbolic_arc_cosine.h @@ -12,7 +12,7 @@ public: // TreeNode size_t size() const override { return sizeof(HyperbolicArcCosineNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "HyperbolicArcCosine"; } #endif @@ -38,7 +38,7 @@ private: class HyperbolicArcCosine final : public HyperbolicTrigonometricFunction { public: HyperbolicArcCosine(const HyperbolicArcCosineNode * n) : HyperbolicTrigonometricFunction(n) {} - static HyperbolicArcCosine Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static HyperbolicArcCosine Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("acosh", 1, &UntypedBuilderOneChild); }; diff --git a/poincare/include/poincare/hyperbolic_arc_sine.h b/poincare/include/poincare/hyperbolic_arc_sine.h index 6e05ccd4e..2981ba622 100644 --- a/poincare/include/poincare/hyperbolic_arc_sine.h +++ b/poincare/include/poincare/hyperbolic_arc_sine.h @@ -12,7 +12,7 @@ public: // TreeNode size_t size() const override { return sizeof(HyperbolicArcSineNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "HyperbolicArcSine"; } #endif @@ -36,7 +36,7 @@ private: class HyperbolicArcSine final : public HyperbolicTrigonometricFunction { public: HyperbolicArcSine(const HyperbolicArcSineNode * n) : HyperbolicTrigonometricFunction(n) {} - static HyperbolicArcSine Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static HyperbolicArcSine Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("asinh", 1, &UntypedBuilderOneChild); }; diff --git a/poincare/include/poincare/hyperbolic_arc_tangent.h b/poincare/include/poincare/hyperbolic_arc_tangent.h index 0280ab98b..d59827696 100644 --- a/poincare/include/poincare/hyperbolic_arc_tangent.h +++ b/poincare/include/poincare/hyperbolic_arc_tangent.h @@ -12,7 +12,7 @@ public: // TreeNode size_t size() const override { return sizeof(HyperbolicArcTangentNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "HyperbolicArcTangent"; } #endif @@ -36,7 +36,7 @@ private: class HyperbolicArcTangent final : public HyperbolicTrigonometricFunction { public: HyperbolicArcTangent(const HyperbolicArcTangentNode * n) : HyperbolicTrigonometricFunction(n) {} - static HyperbolicArcTangent Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static HyperbolicArcTangent Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("atanh", 1, &UntypedBuilderOneChild); }; diff --git a/poincare/include/poincare/hyperbolic_cosine.h b/poincare/include/poincare/hyperbolic_cosine.h index efd9e632d..64f2fc991 100644 --- a/poincare/include/poincare/hyperbolic_cosine.h +++ b/poincare/include/poincare/hyperbolic_cosine.h @@ -12,7 +12,7 @@ public: // TreeNode size_t size() const override { return sizeof(HyperbolicCosineNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "HyperbolicCosine"; } #endif @@ -38,7 +38,7 @@ private: class HyperbolicCosine final : public HyperbolicTrigonometricFunction { public: HyperbolicCosine(const HyperbolicCosineNode * n) : HyperbolicTrigonometricFunction(n) {} - static HyperbolicCosine Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static HyperbolicCosine Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("cosh", 1, &UntypedBuilderOneChild); }; diff --git a/poincare/include/poincare/hyperbolic_sine.h b/poincare/include/poincare/hyperbolic_sine.h index 2f29c8cc9..718aa5ca9 100644 --- a/poincare/include/poincare/hyperbolic_sine.h +++ b/poincare/include/poincare/hyperbolic_sine.h @@ -12,7 +12,7 @@ public: // TreeNode size_t size() const override { return sizeof(HyperbolicSineNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "HyperbolicSine"; } #endif @@ -36,7 +36,7 @@ private: class HyperbolicSine final : public HyperbolicTrigonometricFunction { public: HyperbolicSine(const HyperbolicSineNode * n) : HyperbolicTrigonometricFunction(n) {} - static HyperbolicSine Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static HyperbolicSine Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("sinh", 1, &UntypedBuilderOneChild); }; diff --git a/poincare/include/poincare/hyperbolic_tangent.h b/poincare/include/poincare/hyperbolic_tangent.h index 4e76beccf..5c42b79ba 100644 --- a/poincare/include/poincare/hyperbolic_tangent.h +++ b/poincare/include/poincare/hyperbolic_tangent.h @@ -12,7 +12,7 @@ public: // TreeNode size_t size() const override { return sizeof(HyperbolicTangentNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "HyperbolicTangent"; } #endif @@ -36,7 +36,7 @@ private: class HyperbolicTangent final : public HyperbolicTrigonometricFunction { public: HyperbolicTangent(const HyperbolicTangentNode * n) : HyperbolicTrigonometricFunction(n) {} - static HyperbolicTangent Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static HyperbolicTangent Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("tanh", 1, &UntypedBuilderOneChild); }; diff --git a/poincare/include/poincare/ieee754.h b/poincare/include/poincare/ieee754.h index d2e25d6ce..c1b3c0bcc 100644 --- a/poincare/include/poincare/ieee754.h +++ b/poincare/include/poincare/ieee754.h @@ -53,7 +53,7 @@ public: } static int exponentBase10(T f) { static T k_log10base2 = 3.321928094887362347870319429489390175864831393024580612054; - if (f == 0.0) { + if (f == (T)0.0) { return 0; } T exponentBase2 = exponent(f); @@ -68,7 +68,7 @@ public: * in -0.31 < x < 1, we get: * e2 = [e1/log(10,2)] or e2 = [e1/log(10,2)]-1 depending on m1. */ int exponentBase10 = std::round(exponentBase2/k_log10base2); - if (std::pow(10.0, exponentBase10) > std::fabs(f)) { + if (std::pow((T)10.0, exponentBase10) > std::fabs(f)) { exponentBase10--; } return exponentBase10; diff --git a/poincare/include/poincare/imaginary_part.h b/poincare/include/poincare/imaginary_part.h index 726e22858..345ddbc50 100644 --- a/poincare/include/poincare/imaginary_part.h +++ b/poincare/include/poincare/imaginary_part.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(ImaginaryPartNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "ImaginaryPart"; } #endif @@ -45,7 +45,7 @@ private: class ImaginaryPart final : public Expression { public: ImaginaryPart(const ImaginaryPartNode * n) : Expression(n) {} - static ImaginaryPart Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static ImaginaryPart Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("im", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/infinity.h b/poincare/include/poincare/infinity.h index cc400bfed..2d434f266 100644 --- a/poincare/include/poincare/infinity.h +++ b/poincare/include/poincare/infinity.h @@ -12,7 +12,7 @@ public: // TreeNode size_t size() const override { return sizeof(InfinityNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Infinity"; } virtual void logAttributes(std::ostream & stream) const override { diff --git a/poincare/include/poincare/integer.h b/poincare/include/poincare/integer.h index bb31b9624..181193a75 100644 --- a/poincare/include/poincare/integer.h +++ b/poincare/include/poincare/integer.h @@ -37,7 +37,7 @@ public: int numberOfChildren() const override { return 0; } #if POINCARE_TREE_LOG void log(std::ostream & stream) const; - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Integer"; } virtual void logAttributes(std::ostream & stream) const override; diff --git a/poincare/include/poincare/integral.h b/poincare/include/poincare/integral.h index cd57361c7..e55f30e3a 100644 --- a/poincare/include/poincare/integral.h +++ b/poincare/include/poincare/integral.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(IntegralNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Integral"; } #endif @@ -53,7 +53,7 @@ private: class Integral final : public ParameteredExpression { public: Integral(const IntegralNode * n) : ParameteredExpression(n) {} - static Integral Builder(Expression child0, Symbol child1, Expression child2, Expression child3) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1, child2, child3).array(), 4); } + static Integral Builder(Expression child0, Symbol child1, Expression child2, Expression child3) { return TreeHandle::FixedArityBuilder({child0, child1, child2, child3}); } static Expression UntypedBuilder(Expression children); static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("int", 4, &UntypedBuilder); diff --git a/poincare/include/poincare/integral_layout.h b/poincare/include/poincare/integral_layout.h index c714c8327..84c91eca8 100644 --- a/poincare/include/poincare/integral_layout.h +++ b/poincare/include/poincare/integral_layout.h @@ -31,7 +31,7 @@ public: size_t size() const override { return sizeof(IntegralLayoutNode); } int numberOfChildren() const override { return 4; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "IntegralLayout"; } #endif @@ -61,7 +61,7 @@ private: class IntegralLayout final : public Layout { public: - static IntegralLayout Builder(Layout integrand, Layout differential, Layout lowerBound, Layout upperBound) { return TreeHandle::FixedArityBuilder(ArrayBuilder(integrand, differential, lowerBound, upperBound).array(), 4); } + static IntegralLayout Builder(Layout integrand, Layout differential, Layout lowerBound, Layout upperBound) { return TreeHandle::FixedArityBuilder({integrand, differential, lowerBound, upperBound}); } IntegralLayout() = delete; }; diff --git a/poincare/include/poincare/inv_binom.h b/poincare/include/poincare/inv_binom.h index db0767503..c3b959d60 100644 --- a/poincare/include/poincare/inv_binom.h +++ b/poincare/include/poincare/inv_binom.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(InvBinomNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "InvBinom"; } #endif @@ -38,7 +38,7 @@ private: class InvBinom final : public BinomialDistributionFunction { public: InvBinom(const InvBinomNode * n) : BinomialDistributionFunction(n) {} - static InvBinom Builder(Expression child0, Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1, child2).array(), 3); } + static InvBinom Builder(Expression child0, Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder({child0, child1, child2}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("invbinom", 3, &UntypedBuilderThreeChildren); Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; diff --git a/poincare/include/poincare/inv_norm.h b/poincare/include/poincare/inv_norm.h index edf0a60a6..a06d622e8 100644 --- a/poincare/include/poincare/inv_norm.h +++ b/poincare/include/poincare/inv_norm.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(InvNormNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "InvNorm"; } #endif @@ -38,7 +38,7 @@ private: class InvNorm final : public NormalDistributionFunction { public: InvNorm(const InvNormNode * n) : NormalDistributionFunction(n) {} - static InvNorm Builder(Expression child0, Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1, child2).array(), 3); } + static InvNorm Builder(Expression child0, Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder({child0, child1, child2}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("invnorm", 3, &UntypedBuilderThreeChildren); Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; diff --git a/poincare/include/poincare/layout.h b/poincare/include/poincare/layout.h index d24294289..074943a69 100644 --- a/poincare/include/poincare/layout.h +++ b/poincare/include/poincare/layout.h @@ -1,7 +1,6 @@ #ifndef POINCARE_LAYOUT_REFERENCE_H #define POINCARE_LAYOUT_REFERENCE_H -#include #include #include #include diff --git a/poincare/include/poincare/least_common_multiple.h b/poincare/include/poincare/least_common_multiple.h index 6efdcc071..2ca831043 100644 --- a/poincare/include/poincare/least_common_multiple.h +++ b/poincare/include/poincare/least_common_multiple.h @@ -12,7 +12,7 @@ public: size_t size() const override { return sizeof(LeastCommonMultipleNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "LeastCommonMultiple"; } #endif @@ -37,7 +37,7 @@ private: class LeastCommonMultiple final : public Expression { public: LeastCommonMultiple(const LeastCommonMultipleNode * n) : Expression(n) {} - static LeastCommonMultiple Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } + static LeastCommonMultiple Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder({child0, child1}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("lcm", 2, &UntypedBuilderTwoChildren); // Expression diff --git a/poincare/include/poincare/left_parenthesis_layout.h b/poincare/include/poincare/left_parenthesis_layout.h index 7f535042e..96c9726d1 100644 --- a/poincare/include/poincare/left_parenthesis_layout.h +++ b/poincare/include/poincare/left_parenthesis_layout.h @@ -26,7 +26,7 @@ public: // TreeNode #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "LeftParenthesisLayout"; } #endif diff --git a/poincare/include/poincare/left_square_bracket_layout.h b/poincare/include/poincare/left_square_bracket_layout.h index 99630a785..27d28176d 100644 --- a/poincare/include/poincare/left_square_bracket_layout.h +++ b/poincare/include/poincare/left_square_bracket_layout.h @@ -21,7 +21,7 @@ public: // TreeNode size_t size() const override { return sizeof(LeftSquareBracketLayoutNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "LeftSquareBracketLayout"; } #endif diff --git a/poincare/include/poincare/logarithm.h b/poincare/include/poincare/logarithm.h index d799ab0b3..75d23f0f7 100644 --- a/poincare/include/poincare/logarithm.h +++ b/poincare/include/poincare/logarithm.h @@ -15,7 +15,7 @@ public: size_t size() const override { return sizeof(LogarithmNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Logarithm"; } #endif @@ -48,7 +48,7 @@ class Logarithm final : public Expression { friend class LogarithmNode<2>; public: Logarithm(const LogarithmNode<2> * n) : Expression(n) {} - static Logarithm Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder>(ArrayBuilder(child0, child1).array(), 2); } + static Logarithm Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder>({child0, child1}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("log", 2, &UntypedBuilderTwoChildren); Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); @@ -65,7 +65,7 @@ private: class CommonLogarithm : public Expression { public: CommonLogarithm(const LogarithmNode<1> * n) : Expression(n) {} - static CommonLogarithm Builder(Expression child) { return TreeHandle::FixedArityBuilder>(&child, 1); } + static CommonLogarithm Builder(Expression child) { return TreeHandle::FixedArityBuilder>({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("log", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/matrix.h b/poincare/include/poincare/matrix.h index 96f6e73cf..6d8937e3f 100644 --- a/poincare/include/poincare/matrix.h +++ b/poincare/include/poincare/matrix.h @@ -22,7 +22,7 @@ public: int numberOfChildren() const override { return m_numberOfRows*m_numberOfColumns; } void didAddChildAtIndex(int newNumberOfChildren) override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Matrix"; } virtual void logAttributes(std::ostream & stream) const override { diff --git a/poincare/include/poincare/matrix_complex.h b/poincare/include/poincare/matrix_complex.h index a18e74f2f..b895f3151 100644 --- a/poincare/include/poincare/matrix_complex.h +++ b/poincare/include/poincare/matrix_complex.h @@ -25,7 +25,7 @@ public: int numberOfChildren() const override { return m_numberOfRows*m_numberOfColumns; } void didAddChildAtIndex(int newNumberOfChildren) override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "MatrixComplex"; } virtual void logAttributes(std::ostream & stream) const override { diff --git a/poincare/include/poincare/matrix_dimension.h b/poincare/include/poincare/matrix_dimension.h index 2a8e693b5..07c40840d 100644 --- a/poincare/include/poincare/matrix_dimension.h +++ b/poincare/include/poincare/matrix_dimension.h @@ -12,7 +12,7 @@ public: size_t size() const override { return sizeof(MatrixDimensionNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "MatrixDimension"; } #endif @@ -37,7 +37,7 @@ private: class MatrixDimension final : public Expression { public: MatrixDimension(const MatrixDimensionNode * n) : Expression(n) {} - static MatrixDimension Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static MatrixDimension Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("dim", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/matrix_identity.h b/poincare/include/poincare/matrix_identity.h index e998c0f15..8d50b39c3 100644 --- a/poincare/include/poincare/matrix_identity.h +++ b/poincare/include/poincare/matrix_identity.h @@ -11,7 +11,7 @@ public: size_t size() const override { return sizeof(MatrixIdentityNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "MatrixIdentity"; } #endif @@ -35,7 +35,7 @@ private: class MatrixIdentity final : public Expression { public: MatrixIdentity(const MatrixIdentityNode * n) : Expression(n) {} - static MatrixIdentity Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static MatrixIdentity Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("identity", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/matrix_inverse.h b/poincare/include/poincare/matrix_inverse.h index 347688fe2..53fefdf30 100644 --- a/poincare/include/poincare/matrix_inverse.h +++ b/poincare/include/poincare/matrix_inverse.h @@ -12,7 +12,7 @@ public: size_t size() const override { return sizeof(MatrixInverseNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "MatrixInverse"; } #endif @@ -36,7 +36,7 @@ private: class MatrixInverse final : public Expression { public: MatrixInverse(const MatrixInverseNode * n) : Expression(n) {} - static MatrixInverse Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static MatrixInverse Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("inverse", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/matrix_layout.h b/poincare/include/poincare/matrix_layout.h index cda42e202..6cded4cee 100644 --- a/poincare/include/poincare/matrix_layout.h +++ b/poincare/include/poincare/matrix_layout.h @@ -34,7 +34,7 @@ public: // TreeNode size_t size() const override { return sizeof(MatrixLayoutNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "MatrixLayout"; } #endif diff --git a/poincare/include/poincare/matrix_trace.h b/poincare/include/poincare/matrix_trace.h index f4db9b56a..7805cf0d5 100644 --- a/poincare/include/poincare/matrix_trace.h +++ b/poincare/include/poincare/matrix_trace.h @@ -12,7 +12,7 @@ public: size_t size() const override { return sizeof(MatrixTraceNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "MatrixTrace"; } #endif @@ -36,7 +36,7 @@ private: class MatrixTrace final : public Expression { public: MatrixTrace(const MatrixTraceNode * n) : Expression(n) {} - static MatrixTrace Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static MatrixTrace Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("trace", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/matrix_transpose.h b/poincare/include/poincare/matrix_transpose.h index 96970249c..e404c840c 100644 --- a/poincare/include/poincare/matrix_transpose.h +++ b/poincare/include/poincare/matrix_transpose.h @@ -12,7 +12,7 @@ public: size_t size() const override { return sizeof(MatrixTransposeNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "MatrixTranspose"; } #endif @@ -36,7 +36,7 @@ private: class MatrixTranspose final : public Expression { public: MatrixTranspose(const MatrixTransposeNode * n) : Expression(n) {} - static MatrixTranspose Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static MatrixTranspose Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("transpose", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/multiplication.h b/poincare/include/poincare/multiplication.h index c75144cf4..256c1d479 100644 --- a/poincare/include/poincare/multiplication.h +++ b/poincare/include/poincare/multiplication.h @@ -14,7 +14,7 @@ public: // Tree size_t size() const override { return sizeof(MultiplicationNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Multiplication"; } #endif @@ -69,12 +69,12 @@ class Multiplication : public NAryExpression { friend class UnitConvert; public: Multiplication(const MultiplicationNode * n) : NAryExpression(n) {} - static Multiplication Builder() { return TreeHandle::NAryBuilder(); } - 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); } - static Multiplication Builder(Expression e1, Expression e2, Expression e3, Expression e4) { return Multiplication::Builder(ArrayBuilder(e1, e2, e3, e4).array(), 4); } - static Multiplication Builder(Expression * children, size_t numberOfChildren) { return TreeHandle::NAryBuilder(children, numberOfChildren); } + static Multiplication Builder(const Tuple & children = {}) { return TreeHandle::NAryBuilder(convert(children)); } + // TODO: Get rid of those helpers + static Multiplication Builder(Expression e1) { return Multiplication::Builder({e1}); } + static Multiplication Builder(Expression e1, Expression e2) { return Multiplication::Builder({e1, e2}); } + static Multiplication Builder(Expression e1, Expression e2, Expression e3) { return Multiplication::Builder({e1, e2, e3}); } + static Multiplication Builder(Expression e1, Expression e2, Expression e3, Expression e4) { return Multiplication::Builder({e1, e2, e3, e4}); } // Properties int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[], ExpressionNode::SymbolicComputation symbolicComputation) const; diff --git a/poincare/include/poincare/n_ary_expression.h b/poincare/include/poincare/n_ary_expression.h index 4a55a6bfd..6db14d2ed 100644 --- a/poincare/include/poincare/n_ary_expression.h +++ b/poincare/include/poincare/n_ary_expression.h @@ -38,8 +38,8 @@ protected: * than 6144 children which fit in uint16_t. */ uint16_t m_numberOfChildren; private: - int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const override; - int simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const override; + int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override; + int simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override; }; class NAryExpression : public Expression { diff --git a/poincare/include/poincare/naperian_logarithm.h b/poincare/include/poincare/naperian_logarithm.h index 1c3287bbb..b466af839 100644 --- a/poincare/include/poincare/naperian_logarithm.h +++ b/poincare/include/poincare/naperian_logarithm.h @@ -12,7 +12,7 @@ public: size_t size() const override { return sizeof(NaperianLogarithmNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "NaperianLogarithm"; } #endif @@ -46,7 +46,7 @@ private: class NaperianLogarithm final : public Expression { public: NaperianLogarithm(const NaperianLogarithmNode * n) : Expression(n) {} - static NaperianLogarithm Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static NaperianLogarithm Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("ln", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/norm_cdf.h b/poincare/include/poincare/norm_cdf.h index f6d117547..ae9eee78c 100644 --- a/poincare/include/poincare/norm_cdf.h +++ b/poincare/include/poincare/norm_cdf.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(NormCDFNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "NormCDF"; } #endif @@ -37,7 +37,7 @@ private: class NormCDF final : public NormalDistributionFunction { public: NormCDF(const NormCDFNode * n) : NormalDistributionFunction(n) {} - static NormCDF Builder(Expression child0, Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1, child2).array(), 3); } + static NormCDF Builder(Expression child0, Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder({child0, child1, child2}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("normcdf", 3, &UntypedBuilderThreeChildren); }; diff --git a/poincare/include/poincare/norm_cdf2.h b/poincare/include/poincare/norm_cdf2.h index 08167c0bd..2db2965a4 100644 --- a/poincare/include/poincare/norm_cdf2.h +++ b/poincare/include/poincare/norm_cdf2.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(NormCDF2Node); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "NormCDF2"; } #endif @@ -39,7 +39,7 @@ private: class NormCDF2 final : public NormalDistributionFunction { public: NormCDF2(const NormCDF2Node * n) : NormalDistributionFunction(n) {} - static NormCDF2 Builder(Expression child0, Expression child1, Expression child2, Expression child3) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1, child2, child3).array(), 4); } + static NormCDF2 Builder(Expression child0, Expression child1, Expression child2, Expression child3) { return TreeHandle::FixedArityBuilder({child0, child1, child2, child3}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("normcdf2", 4, &UntypedBuilderFourChildren); }; diff --git a/poincare/include/poincare/norm_pdf.h b/poincare/include/poincare/norm_pdf.h index e7c8ac58c..5467a478e 100644 --- a/poincare/include/poincare/norm_pdf.h +++ b/poincare/include/poincare/norm_pdf.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(NormPDFNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "NormPDF"; } #endif @@ -37,7 +37,7 @@ private: class NormPDF final : public NormalDistributionFunction { public: NormPDF(const NormPDFNode * n) : NormalDistributionFunction(n) {} - static NormPDF Builder(Expression child0, Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1, child2).array(), 3); } + static NormPDF Builder(Expression child0, Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder({child0, child1, child2}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("normpdf", 3, &UntypedBuilderThreeChildren); }; diff --git a/poincare/include/poincare/nth_root.h b/poincare/include/poincare/nth_root.h index 3edec4e1c..d0d1d8e87 100644 --- a/poincare/include/poincare/nth_root.h +++ b/poincare/include/poincare/nth_root.h @@ -14,7 +14,7 @@ public: size_t size() const override { return sizeof(NthRootNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "NthRoot"; } #endif @@ -38,7 +38,7 @@ private: class NthRoot final : public Expression { public: NthRoot(const NthRootNode * n) : Expression(n) {} - static NthRoot Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } + static NthRoot Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder({child0, child1}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("root", 2, &UntypedBuilderTwoChildren); Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); diff --git a/poincare/include/poincare/nth_root_layout.h b/poincare/include/poincare/nth_root_layout.h index ba5cff8ce..b7644f993 100644 --- a/poincare/include/poincare/nth_root_layout.h +++ b/poincare/include/poincare/nth_root_layout.h @@ -38,7 +38,7 @@ public: size_t size() const override { return sizeof(NthRootLayoutNode); } int numberOfChildren() const override { return m_hasIndex ? 2 : 1; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "NthRootLayout"; } #endif diff --git a/poincare/include/poincare/opposite.h b/poincare/include/poincare/opposite.h index 58d0462c0..c4fc89166 100644 --- a/poincare/include/poincare/opposite.h +++ b/poincare/include/poincare/opposite.h @@ -17,7 +17,7 @@ public: size_t size() const override { return sizeof(OppositeNode); } int numberOfChildren() const override { return 1; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Opposite"; } #endif @@ -50,7 +50,7 @@ class Opposite final : public Expression { public: Opposite(const OppositeNode * n) : Expression(n) {} static Opposite Builder() { return TreeHandle::FixedArityBuilder(); } - static Opposite Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static Opposite Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; diff --git a/poincare/include/poincare/parenthesis.h b/poincare/include/poincare/parenthesis.h index ec203e55b..067898502 100644 --- a/poincare/include/poincare/parenthesis.h +++ b/poincare/include/poincare/parenthesis.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(ParenthesisNode); } int numberOfChildren() const override { return 1; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Parenthesis"; } #endif @@ -40,7 +40,7 @@ private: class Parenthesis final : public Expression { public: Parenthesis(const ParenthesisNode * n) : Expression(n) {} - static Parenthesis Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static Parenthesis Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } // Expression Expression shallowReduce(); }; diff --git a/poincare/include/poincare/parenthesis_layout.h b/poincare/include/poincare/parenthesis_layout.h index f35679205..8d2330139 100644 --- a/poincare/include/poincare/parenthesis_layout.h +++ b/poincare/include/poincare/parenthesis_layout.h @@ -21,7 +21,7 @@ public: // TreeNode size_t size() const override { return sizeof(ParenthesisLayoutNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "ParenthesisLayout"; } #endif diff --git a/poincare/include/poincare/permute_coefficient.h b/poincare/include/poincare/permute_coefficient.h index 63ee987fa..1bc05924b 100644 --- a/poincare/include/poincare/permute_coefficient.h +++ b/poincare/include/poincare/permute_coefficient.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(PermuteCoefficientNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "PermuteCoefficient"; } #endif @@ -41,7 +41,7 @@ private: class PermuteCoefficient final : public Expression { public: PermuteCoefficient(const PermuteCoefficientNode * n) : Expression(n) {} - static PermuteCoefficient Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } + static PermuteCoefficient Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder({child0, child1}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("permute", 2, &UntypedBuilderTwoChildren); // Expression diff --git a/poincare/include/poincare/power.h b/poincare/include/poincare/power.h index 77f2dda77..ad269d15d 100644 --- a/poincare/include/poincare/power.h +++ b/poincare/include/poincare/power.h @@ -16,7 +16,7 @@ public: size_t size() const override { return sizeof(PowerNode); } int numberOfChildren() const override { return 2; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Power"; } #endif @@ -52,8 +52,8 @@ private: Expression shallowBeautify(ReductionContext reductionContext) override; LayoutShape leftLayoutShape() const override { return childAtIndex(0)->leftLayoutShape(); } LayoutShape rightLayoutShape() const override { return LayoutShape::RightOfPower; } - int simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const override; - int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const override; + int simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override; + int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override; Expression denominator(ReductionContext reductionContext) const override; // Evaluation template static MatrixComplex computeOnComplexAndMatrix(const std::complex c, const MatrixComplex n, Preferences::ComplexFormat complexFormat); @@ -73,7 +73,7 @@ class Power final : public Expression { friend class Round; public: Power(const PowerNode * n) : Expression(n) {} - static Power Builder(Expression base, Expression exponent) { return TreeHandle::FixedArityBuilder(ArrayBuilder(base, exponent).array(), 2); } + static Power Builder(Expression base, Expression exponent) { return TreeHandle::FixedArityBuilder({base, exponent}); } Expression setSign(ExpressionNode::Sign s, ExpressionNode::ReductionContext reductionContext); int getPolynomialCoefficients(Context * context, const char * symbolName, Expression coefficients[]) const; diff --git a/poincare/include/poincare/prediction_interval.h b/poincare/include/poincare/prediction_interval.h index de628ec01..734b2ba22 100644 --- a/poincare/include/poincare/prediction_interval.h +++ b/poincare/include/poincare/prediction_interval.h @@ -12,7 +12,7 @@ public: size_t size() const override { return sizeof(PredictionIntervalNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "PredictionInterval"; } #endif @@ -39,7 +39,7 @@ private: class PredictionInterval final : public Expression { public: PredictionInterval(const PredictionIntervalNode * n) : Expression(n) {} - static PredictionInterval Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } + static PredictionInterval Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder({child0, child1}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("prediction95", 2, &UntypedBuilderTwoChildren); // Expression diff --git a/poincare/include/poincare/product.h b/poincare/include/poincare/product.h index c70d2bfbb..140fe5c4f 100644 --- a/poincare/include/poincare/product.h +++ b/poincare/include/poincare/product.h @@ -10,7 +10,7 @@ public: // TreeNode size_t size() const override { return sizeof(ProductNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Product"; } #endif @@ -34,7 +34,7 @@ class Product final : public Sequence { friend class ProductNode; public: Product(const ProductNode * n) : Sequence(n) {} - static Product Builder(Expression child0, Symbol child1, Expression child2, Expression child3) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1, child2, child3).array(), 4); } + static Product Builder(Expression child0, Symbol child1, Expression child2, Expression child3) { return TreeHandle::FixedArityBuilder({child0, child1, child2, child3}); } static Expression UntypedBuilder(Expression children); static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("product", 4, &UntypedBuilder); diff --git a/poincare/include/poincare/product_layout.h b/poincare/include/poincare/product_layout.h index 85035cfe8..79657f37f 100644 --- a/poincare/include/poincare/product_layout.h +++ b/poincare/include/poincare/product_layout.h @@ -16,7 +16,7 @@ public: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; size_t size() const override { return sizeof(ProductLayoutNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "ProductLayout"; } #endif @@ -29,7 +29,7 @@ private: class ProductLayout final : public Layout { public: - static ProductLayout Builder(Layout argument, Layout variable, Layout lowerB, Layout upperB) { return TreeHandle::FixedArityBuilder(ArrayBuilder(argument, variable, lowerB, upperB).array(), 4); } + static ProductLayout Builder(Layout argument, Layout variable, Layout lowerB, Layout upperB) { return TreeHandle::FixedArityBuilder({argument, variable, lowerB, upperB}); } ProductLayout() = delete; }; diff --git a/poincare/include/poincare/randint.h b/poincare/include/poincare/randint.h index 62870714e..b8f03edc3 100644 --- a/poincare/include/poincare/randint.h +++ b/poincare/include/poincare/randint.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(RandintNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Randint"; } #endif @@ -45,7 +45,7 @@ class Randint final : public Expression { friend class RandintNode; public: Randint(const RandintNode * n) : Expression(n) {} - static Randint Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } + static Randint Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder({child0, child1}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("randint", 2, &UntypedBuilderTwoChildren); private: Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); diff --git a/poincare/include/poincare/random.h b/poincare/include/poincare/random.h index fcb93572f..564a758ed 100644 --- a/poincare/include/poincare/random.h +++ b/poincare/include/poincare/random.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(RandomNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Random"; } #endif diff --git a/poincare/include/poincare/rational.h b/poincare/include/poincare/rational.h index 84da9e017..4e16c5cf0 100644 --- a/poincare/include/poincare/rational.h +++ b/poincare/include/poincare/rational.h @@ -21,7 +21,7 @@ public: // TreeNode size_t size() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Rational"; } virtual void logAttributes(std::ostream & stream) const override; @@ -52,7 +52,7 @@ public: static int NaturalOrder(const RationalNode * i, const RationalNode * j); private: - int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const override; + int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override; Expression shallowReduce(ReductionContext reductionContext) override; Expression shallowBeautify(ReductionContext reductionContext) override; LayoutShape leftLayoutShape() const override { assert(!m_negative); return isInteger() ? LayoutShape::Integer : LayoutShape::Fraction; }; diff --git a/poincare/include/poincare/real_part.h b/poincare/include/poincare/real_part.h index 787ad80b1..ddcbd24a7 100644 --- a/poincare/include/poincare/real_part.h +++ b/poincare/include/poincare/real_part.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(RealPartNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "RealPart"; } #endif @@ -45,7 +45,7 @@ private: class RealPart final : public Expression { public: RealPart(const RealPartNode * n) : Expression(n) {} - static RealPart Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static RealPart Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("re", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/right_parenthesis_layout.h b/poincare/include/poincare/right_parenthesis_layout.h index fac6ad338..1f30b6140 100644 --- a/poincare/include/poincare/right_parenthesis_layout.h +++ b/poincare/include/poincare/right_parenthesis_layout.h @@ -27,7 +27,7 @@ public: // TreeNode size_t size() const override { return sizeof(RightParenthesisLayoutNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "RightParenthesisLayout"; } #endif diff --git a/poincare/include/poincare/right_square_bracket_layout.h b/poincare/include/poincare/right_square_bracket_layout.h index 62fabddb1..760e95fe9 100644 --- a/poincare/include/poincare/right_square_bracket_layout.h +++ b/poincare/include/poincare/right_square_bracket_layout.h @@ -21,7 +21,7 @@ public: // TreeNode size_t size() const override { return sizeof(RightSquareBracketLayoutNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "RightSquareBracketLayout"; } #endif diff --git a/poincare/include/poincare/round.h b/poincare/include/poincare/round.h index 158c2b36d..bb4a769aa 100644 --- a/poincare/include/poincare/round.h +++ b/poincare/include/poincare/round.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(RoundNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Round"; } #endif @@ -38,7 +38,7 @@ private: class Round final : public Expression { public: Round(const RoundNode * n) : Expression(n) {} - static Round Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } + static Round Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder({child0, child1}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("round", 2, &UntypedBuilderTwoChildren); Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); diff --git a/poincare/include/poincare/sign_function.h b/poincare/include/poincare/sign_function.h index f11b0fb13..d5379058a 100644 --- a/poincare/include/poincare/sign_function.h +++ b/poincare/include/poincare/sign_function.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(SignFunctionNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "SignFunction"; } #endif @@ -45,7 +45,7 @@ private: class SignFunction final : public Expression { public: SignFunction(const SignFunctionNode * n) : Expression(n) {} - static SignFunction Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static SignFunction Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("sign", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/sine.h b/poincare/include/poincare/sine.h index 0239b50e0..80307a048 100644 --- a/poincare/include/poincare/sine.h +++ b/poincare/include/poincare/sine.h @@ -14,7 +14,7 @@ public: size_t size() const override { return sizeof(SineNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Sine"; } #endif @@ -47,7 +47,7 @@ private: class Sine final : public Expression { public: Sine(const SineNode * n) : Expression(n) {} - static Sine Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static Sine Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("sin", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/square_root.h b/poincare/include/poincare/square_root.h index aeca57862..6a46aee29 100644 --- a/poincare/include/poincare/square_root.h +++ b/poincare/include/poincare/square_root.h @@ -16,7 +16,7 @@ public: size_t size() const override { return sizeof(SquareRootNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "SquareRoot"; } #endif @@ -41,7 +41,7 @@ private: class SquareRoot final : public Expression { public: SquareRoot(const SquareRootNode * n) : Expression(n) {} - static SquareRoot Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static SquareRoot Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("√", 1, &UntypedBuilderOneChild); Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); }; diff --git a/poincare/include/poincare/store.h b/poincare/include/poincare/store.h index 5c48f1b38..95bd3c146 100644 --- a/poincare/include/poincare/store.h +++ b/poincare/include/poincare/store.h @@ -12,7 +12,7 @@ public: // TreeNode size_t size() const override { return sizeof(StoreNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Store"; } #endif @@ -32,7 +32,7 @@ class Store final : public Expression { friend class StoreNode; public: Store(const StoreNode * n) : Expression(n) {} - static Store Builder(Expression value, SymbolAbstract symbol) { return TreeHandle::FixedArityBuilder(ArrayBuilder(value, symbol).array(), 2); } + static Store Builder(Expression value, SymbolAbstract symbol) { return TreeHandle::FixedArityBuilder({value, symbol}); } // Store const SymbolAbstract symbol() const { diff --git a/poincare/include/poincare/subtraction.h b/poincare/include/poincare/subtraction.h index 53b77bc60..f8703648e 100644 --- a/poincare/include/poincare/subtraction.h +++ b/poincare/include/poincare/subtraction.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(SubtractionNode); } int numberOfChildren() const override { return 2; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Subtraction"; } #endif @@ -62,7 +62,7 @@ class Subtraction final : public Expression { public: Subtraction(const SubtractionNode * n) : Expression(n) {} static Subtraction Builder() { return TreeHandle::FixedArityBuilder(); } - static Subtraction Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1).array(), 2); } + static Subtraction Builder(Expression child0, Expression child1) { return TreeHandle::FixedArityBuilder({child0, child1}); } // Expression Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); diff --git a/poincare/include/poincare/sum.h b/poincare/include/poincare/sum.h index e2dfcec88..af1542203 100644 --- a/poincare/include/poincare/sum.h +++ b/poincare/include/poincare/sum.h @@ -10,7 +10,7 @@ public: // TreeNode size_t size() const override { return sizeof(SumNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Sum"; } #endif @@ -34,7 +34,7 @@ class Sum final : public Sequence { friend class SumNode; public: Sum(const SumNode * n) : Sequence(n) {} - static Sum Builder(Expression child0, Symbol child1, Expression child2, Expression child3) { return TreeHandle::FixedArityBuilder(ArrayBuilder(child0, child1, child2, child3).array(), 4); } + static Sum Builder(Expression child0, Symbol child1, Expression child2, Expression child3) { return TreeHandle::FixedArityBuilder({child0, child1, child2, child3}); } static Expression UntypedBuilder(Expression children); static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("sum", 4, &UntypedBuilder); diff --git a/poincare/include/poincare/sum_layout.h b/poincare/include/poincare/sum_layout.h index 15a15fbff..0505b5226 100644 --- a/poincare/include/poincare/sum_layout.h +++ b/poincare/include/poincare/sum_layout.h @@ -16,7 +16,7 @@ public: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; size_t size() const override { return sizeof(SumLayoutNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "SumLayout"; } #endif @@ -27,7 +27,7 @@ private: class SumLayout final : public Layout { public: - static SumLayout Builder(Layout argument, Layout variable, Layout lowerB, Layout upperB) { return TreeHandle::FixedArityBuilder(ArrayBuilder(argument, variable, lowerB, upperB).array(), 4); } + static SumLayout Builder(Layout argument, Layout variable, Layout lowerB, Layout upperB) { return TreeHandle::FixedArityBuilder({argument, variable, lowerB, upperB}); } SumLayout() = delete; }; diff --git a/poincare/include/poincare/symbol.h b/poincare/include/poincare/symbol.h index e441c8e27..9c78b8c43 100644 --- a/poincare/include/poincare/symbol.h +++ b/poincare/include/poincare/symbol.h @@ -14,7 +14,7 @@ public: // TreeNode int numberOfChildren() const override { return 0; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Symbol"; } #endif diff --git a/poincare/include/poincare/symbol_abstract.h b/poincare/include/poincare/symbol_abstract.h index fab4c79a9..02b2e79a8 100644 --- a/poincare/include/poincare/symbol_abstract.h +++ b/poincare/include/poincare/symbol_abstract.h @@ -29,7 +29,7 @@ public: size_t size() const override; // ExpressionNode - int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const override; + int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override; // Property Sign sign(Context * context) const override; @@ -37,7 +37,7 @@ public: // TreeNode #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "SymbolAbstract"; } virtual void logAttributes(std::ostream & stream) const override { diff --git a/poincare/include/poincare/tangent.h b/poincare/include/poincare/tangent.h index 879d8b679..ee0891038 100644 --- a/poincare/include/poincare/tangent.h +++ b/poincare/include/poincare/tangent.h @@ -13,7 +13,7 @@ public: size_t size() const override { return sizeof(TangentNode); } int numberOfChildren() const override; #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Tangent"; } #endif @@ -45,7 +45,7 @@ private: class Tangent final : public Expression { public: Tangent(const TangentNode * n) : Expression(n) {} - static Tangent Builder(Expression child) { return TreeHandle::FixedArityBuilder(&child, 1); } + static Tangent Builder(Expression child) { return TreeHandle::FixedArityBuilder({child}); } static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("tan", 1, &UntypedBuilderOneChild); diff --git a/poincare/include/poincare/tree_handle.h b/poincare/include/poincare/tree_handle.h index 5e2a07d9b..b171871b6 100644 --- a/poincare/include/poincare/tree_handle.h +++ b/poincare/include/poincare/tree_handle.h @@ -2,7 +2,7 @@ #define POINCARE_TREE_BY_REFERENCE_H #include -#include +#include namespace Shared { class ContinuousFunction; @@ -23,8 +23,6 @@ namespace Poincare { * equivalent to Logarithm l = Logarithm(clone())). */ class TreeHandle { - template - friend class ArrayBuilder; friend class ::Shared::ContinuousFunction; friend class TreeNode; friend class TreePool; @@ -107,6 +105,8 @@ public: void log() const; #endif + typedef std::initializer_list Tuple; + protected: /* Constructor */ TreeHandle(const TreeNode * node); @@ -119,9 +119,9 @@ protected: // WARNING: if the children table is the result of a cast, the object downcasted has to be the same size as a TreeHandle. template - static T NAryBuilder(TreeHandle * children = nullptr, size_t numberOfChildren = 0); + static T NAryBuilder(const Tuple & children = {}); template - static T FixedArityBuilder(TreeHandle * children = nullptr, size_t numberOfChildren = 0); + static T FixedArityBuilder(const Tuple & children = {}); static TreeHandle BuildWithGhostChildren(TreeNode * node); diff --git a/poincare/include/poincare/undefined.h b/poincare/include/poincare/undefined.h index 83a7d8e3f..90f0078e3 100644 --- a/poincare/include/poincare/undefined.h +++ b/poincare/include/poincare/undefined.h @@ -11,7 +11,7 @@ public: // TreeNode size_t size() const override { return sizeof(UndefinedNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Undefined"; } #endif diff --git a/poincare/include/poincare/unit.h b/poincare/include/poincare/unit.h index 97021c50c..d1938008f 100644 --- a/poincare/include/poincare/unit.h +++ b/poincare/include/poincare/unit.h @@ -102,7 +102,7 @@ public: size_t size() const override { return sizeof(UnitNode); } int numberOfChildren() const override { return 0; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Unit"; } virtual void logAttributes(std::ostream & stream) const override { @@ -125,7 +125,7 @@ public: Evaluation approximate(DoublePrecision p, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, complexFormat, angleUnit); } // Comparison - int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const override; + int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override; // Simplification Expression shallowReduce(ReductionContext reductionContext) override; diff --git a/poincare/include/poincare/unit_convert.h b/poincare/include/poincare/unit_convert.h index 7125b6ed3..70943a9f5 100644 --- a/poincare/include/poincare/unit_convert.h +++ b/poincare/include/poincare/unit_convert.h @@ -12,7 +12,7 @@ public: // TreeNode size_t size() const override { return sizeof(UnitConvertNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "UnivtConvert"; } #endif @@ -33,7 +33,7 @@ class UnitConvert final : public Expression { friend class UnitConvertNode; public: UnitConvert(const UnitConvertNode * n) : Expression(n) {} - static UnitConvert Builder(Expression value, Expression unit) { return TreeHandle::FixedArityBuilder(ArrayBuilder(value, unit).array(), 2); } + static UnitConvert Builder(Expression value, Expression unit) { return TreeHandle::FixedArityBuilder({value, unit}); } // Expression Expression shallowReduce(ExpressionNode::ReductionContext reductionContext); diff --git a/poincare/include/poincare/unreal.h b/poincare/include/poincare/unreal.h index 283013752..4b31ef182 100644 --- a/poincare/include/poincare/unreal.h +++ b/poincare/include/poincare/unreal.h @@ -11,7 +11,7 @@ public: // TreeNode size_t size() const override { return sizeof(UnrealNode); } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Unreal"; } #endif diff --git a/poincare/include/poincare/vertical_offset_layout.h b/poincare/include/poincare/vertical_offset_layout.h index 5a36cc666..4411667e3 100644 --- a/poincare/include/poincare/vertical_offset_layout.h +++ b/poincare/include/poincare/vertical_offset_layout.h @@ -38,7 +38,7 @@ public: size_t size() const override { return sizeof(VerticalOffsetLayoutNode); } int numberOfChildren() const override { return 1; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << (m_position == Position::Subscript ? "Subscript" : "Superscript"); } #endif diff --git a/poincare/src/approximation_helper.cpp b/poincare/src/approximation_helper.cpp index c82371cb4..30439ad9c 100644 --- a/poincare/src/approximation_helper.cpp +++ b/poincare/src/approximation_helper.cpp @@ -19,7 +19,7 @@ template < typename T> T minimalNonNullMagnitudeOfParts(std::complex c) { T absRealInput = std::fabs(c.real()); T absImagInput = std::fabs(c.imag()); // If the magnitude of one part is null, ignore it - if (absRealInput == 0.0 || (absImagInput > 0.0 && absImagInput < absRealInput)) { + if (absRealInput == (T)0.0 || (absImagInput > (T)0.0 && absImagInput < absRealInput)) { return absImagInput; } return absRealInput; @@ -52,7 +52,7 @@ template std::complex ApproximationHelper::NeglectRealOrImaginar } T magnitude1 = minimalNonNullMagnitudeOfParts(input1); T magnitude2 = minimalNonNullMagnitudeOfParts(input2); - T precision = 10.0*Expression::Epsilon(); + T precision = ((T)10.0)*Expression::Epsilon(); if (isNegligeable(result.imag(), precision, magnitude1, magnitude2)) { result.imag(0); } diff --git a/poincare/src/arc_cosine.cpp b/poincare/src/arc_cosine.cpp index 9f27e4f5d..b7bd085ae 100644 --- a/poincare/src/arc_cosine.cpp +++ b/poincare/src/arc_cosine.cpp @@ -26,7 +26,7 @@ Expression ArcCosineNode::shallowReduce(ReductionContext reductionContext) { template Complex ArcCosineNode::computeOnComplex(const std::complex c, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) { std::complex result; - if (c.imag() == 0 && std::fabs(c.real()) <= 1.0) { + if (c.imag() == 0 && std::fabs(c.real()) <= (T)1.0) { /* acos: [-1;1] -> R * In these cases we rather use std::acos(double) because acos on complexes * is not as precise as pow on double in std library. For instance, diff --git a/poincare/src/arc_sine.cpp b/poincare/src/arc_sine.cpp index 4d7100ac8..7168da4e1 100644 --- a/poincare/src/arc_sine.cpp +++ b/poincare/src/arc_sine.cpp @@ -26,7 +26,7 @@ Expression ArcSineNode::shallowReduce(ReductionContext reductionContext) { template Complex ArcSineNode::computeOnComplex(const std::complex c, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) { std::complex result; - if (c.imag() == 0 && std::fabs(c.real()) <= 1.0) { + if (c.imag() == 0 && std::fabs(c.real()) <= (T)1.0) { /* asin: [-1;1] -> R * In these cases we rather use std::asin(double) because asin on complexes * is not as precise as asin on double in std library. For instance, diff --git a/poincare/src/arc_tangent.cpp b/poincare/src/arc_tangent.cpp index 19bb310bb..cdfda478f 100644 --- a/poincare/src/arc_tangent.cpp +++ b/poincare/src/arc_tangent.cpp @@ -22,7 +22,7 @@ int ArcTangentNode::serialize(char * buffer, int bufferSize, Preferences::PrintF template Complex ArcTangentNode::computeOnComplex(const std::complex c, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) { std::complex result; - if (c.imag() == 0 && std::fabs(c.real()) <= 1.0) { + if (c.imag() == 0 && std::fabs(c.real()) <= (T)1.0) { /* atan: R -> R * In these cases we rather use std::atan(double) because atan on complexes * is not as precise as atan on double in std library. For instance, diff --git a/poincare/src/binomial_coefficient_layout.cpp b/poincare/src/binomial_coefficient_layout.cpp index 962a42894..dd93b9e2e 100644 --- a/poincare/src/binomial_coefficient_layout.cpp +++ b/poincare/src/binomial_coefficient_layout.cpp @@ -4,11 +4,10 @@ #include #include #include +#include namespace Poincare { -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } - void BinomialCoefficientLayoutNode::moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout, bool forSelection) { if (cursor->position() == LayoutCursor::Position::Left && (cursor->layoutNode() == nLayout() @@ -79,7 +78,7 @@ int BinomialCoefficientLayoutNode::serialize(char * buffer, int bufferSize, Pref KDSize BinomialCoefficientLayoutNode::computeSize() { KDSize coefficientsSize = KDSize( - maxCoordinate(nLayout()->layoutSize().width(), kLayout()->layoutSize().width()), + std::max(nLayout()->layoutSize().width(), kLayout()->layoutSize().width()), knHeight()); KDCoordinate width = coefficientsSize.width() + 2*ParenthesisLayoutNode::ParenthesisWidth(); return KDSize(width, coefficientsSize.height()); @@ -90,7 +89,7 @@ KDCoordinate BinomialCoefficientLayoutNode::computeBaseline() { } KDPoint BinomialCoefficientLayoutNode::positionOfChild(LayoutNode * child) { - KDCoordinate horizontalCenter = ParenthesisLayoutNode::ParenthesisWidth() + maxCoordinate(nLayout()->layoutSize().width(), kLayout()->layoutSize().width())/2; + KDCoordinate horizontalCenter = ParenthesisLayoutNode::ParenthesisWidth() + std::max(nLayout()->layoutSize().width(), kLayout()->layoutSize().width())/2; if (child == nLayout()) { return KDPoint(horizontalCenter - nLayout()->layoutSize().width()/2, 0); } @@ -101,9 +100,9 @@ KDPoint BinomialCoefficientLayoutNode::positionOfChild(LayoutNode * child) { void BinomialCoefficientLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor, Layout * selectionStart, Layout * selectionEnd, KDColor selectionColor) { // Render the parentheses. KDCoordinate childHeight = knHeight(); - KDCoordinate rightParenthesisPointX = maxCoordinate(nLayout()->layoutSize().width(), kLayout()->layoutSize().width()) + LeftParenthesisLayoutNode::ParenthesisWidth(); + KDCoordinate rightParenthesisPointX = std::max(nLayout()->layoutSize().width(), kLayout()->layoutSize().width()) + LeftParenthesisLayoutNode::ParenthesisWidth(); LeftParenthesisLayoutNode::RenderWithChildHeight(childHeight, ctx, p, expressionColor, backgroundColor); RightParenthesisLayoutNode::RenderWithChildHeight(childHeight, ctx, p.translatedBy(KDPoint(rightParenthesisPointX, 0)), expressionColor, backgroundColor); } -} \ No newline at end of file +} diff --git a/poincare/src/bracket_layout.cpp b/poincare/src/bracket_layout.cpp index fa883e17c..fa9c08854 100644 --- a/poincare/src/bracket_layout.cpp +++ b/poincare/src/bracket_layout.cpp @@ -2,11 +2,10 @@ #include #include #include +#include namespace Poincare { -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } - void BracketLayoutNode::moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout, bool forSelection) { assert(cursor->layoutNode() == this); if (cursor->position() == LayoutCursor::Position::Right) { @@ -84,7 +83,7 @@ KDCoordinate BracketLayoutNode::computeBaseline() { { currentNumberOfOpenBrackets++; } - result = maxCoordinate(result, sibling->baseline()); + result = std::max(result, sibling->baseline()); } return result + (layoutSize().height() - childHeight()) / 2; } @@ -138,10 +137,10 @@ KDCoordinate BracketLayoutNode::computeChildHeight() { } KDCoordinate siblingHeight = sibling->layoutSize().height(); KDCoordinate siblingBaseline = sibling->baseline(); - maxUnderBaseline = maxCoordinate(maxUnderBaseline, siblingHeight - siblingBaseline); - maxAboveBaseline = maxCoordinate(maxAboveBaseline, siblingBaseline); + maxUnderBaseline = std::max(maxUnderBaseline, siblingHeight - siblingBaseline); + maxAboveBaseline = std::max(maxAboveBaseline, siblingBaseline); } - return maxCoordinate(result, maxUnderBaseline + maxAboveBaseline); + return std::max(result, maxUnderBaseline + maxAboveBaseline); } KDPoint BracketLayoutNode::positionOfChild(LayoutNode * child) { diff --git a/poincare/src/complex.cpp b/poincare/src/complex.cpp index b78b6fc69..a9e022101 100644 --- a/poincare/src/complex.cpp +++ b/poincare/src/complex.cpp @@ -26,7 +26,7 @@ ComplexNode::ComplexNode(std::complex c) : EvaluationNode(), std::complex(c.real(), c.imag()) { - if (!std::isnan(c.imag()) && c.imag() != 0.0) { + if (!std::isnan(c.imag()) && c.imag() != (T)0.0) { Expression::SetEncounteredComplex(true); } if (this->real() == -0) { @@ -39,7 +39,7 @@ ComplexNode::ComplexNode(std::complex c) : template T ComplexNode::toScalar() const { - if (this->imag() == 0.0) { + if (this->imag() == (T)0.0) { return this->real(); } return NAN; @@ -63,7 +63,7 @@ Expression ComplexNode::complexToExpression(Preferences::ComplexFormat comple Number::DecimalNumber(std::fabs(tb)), complexFormat, (std::isnan(this->real()) || std::isnan(this->imag())), - ra == 0.0, std::fabs(ra) == 1.0, tb == 0.0, std::fabs(tb) == 1.0, ra < 0.0, tb < 0.0 + ra == (T)0.0, std::fabs(ra) == (T)1.0, tb == (T)0.0, std::fabs(tb) == (T)1.0, ra < (T)0.0, tb < (T)0.0 ); } diff --git a/poincare/src/complex_cartesian.cpp b/poincare/src/complex_cartesian.cpp index 0d8933192..da5db5d74 100644 --- a/poincare/src/complex_cartesian.cpp +++ b/poincare/src/complex_cartesian.cpp @@ -35,7 +35,7 @@ Complex ComplexCartesianNode::templatedApproximate(Context * context, Prefere assert(imagEvalution.type() == EvaluationNode::Type::Complex); std::complex a = static_cast &>(realEvaluation).stdComplex(); std::complex b = static_cast &>(imagEvalution).stdComplex(); - if ((a.imag() != 0.0 && !std::isnan(a.imag())) || (b.imag() != 0.0 && !std::isnan(b.imag()))) { + if ((a.imag() != (T)0.0 && !std::isnan(a.imag())) || (b.imag() != (T)0.0 && !std::isnan(b.imag()))) { /* a and b are supposed to be real (if they are not undefined). However, * due to double precision limit, the approximation of the real part or the * imaginary part can lead to complex values. diff --git a/poincare/src/condensed_sum_layout.cpp b/poincare/src/condensed_sum_layout.cpp index 096699e9d..8843a321a 100644 --- a/poincare/src/condensed_sum_layout.cpp +++ b/poincare/src/condensed_sum_layout.cpp @@ -1,21 +1,20 @@ #include #include #include +#include namespace Poincare { -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } - KDCoordinate CondensedSumLayoutNode::computeBaseline() { - return baseLayout()->baseline() + maxCoordinate(0, superscriptLayout()->layoutSize().height() - baseLayout()->layoutSize().height()/2); + return baseLayout()->baseline() + std::max(0, superscriptLayout()->layoutSize().height() - baseLayout()->layoutSize().height()/2); } KDSize CondensedSumLayoutNode::computeSize() { KDSize baseSize = baseLayout()->layoutSize(); KDSize subscriptSize = subscriptLayout()->layoutSize(); KDSize superscriptSize = superscriptLayout()->layoutSize(); - KDCoordinate sizeWidth = baseSize.width() + maxCoordinate(subscriptSize.width(), superscriptSize.width()); - KDCoordinate sizeHeight = maxCoordinate(baseSize.height()/2, subscriptSize.height()) + maxCoordinate(baseSize.height()/2, superscriptSize.height()); + KDCoordinate sizeWidth = baseSize.width() + std::max(subscriptSize.width(), superscriptSize.width()); + KDCoordinate sizeHeight = std::max(baseSize.height()/2, subscriptSize.height()) + std::max(baseSize.height()/2, superscriptSize.height()); return KDSize(sizeWidth, sizeHeight); } @@ -25,11 +24,11 @@ KDPoint CondensedSumLayoutNode::positionOfChild(LayoutNode * child) { KDSize baseSize = baseLayout()->layoutSize(); KDSize superscriptSize = superscriptLayout()->layoutSize(); if (child == baseLayout()) { - y = maxCoordinate(0, superscriptSize.height() - baseSize.height()/2); + y = std::max(0, superscriptSize.height() - baseSize.height()/2); } if (child == subscriptLayout()) { x = baseSize.width(); - y = maxCoordinate(baseSize.height()/2, superscriptSize.height()); + y = std::max(baseSize.height()/2, superscriptSize.height()); } if (child == superscriptLayout()) { x = baseSize.width(); diff --git a/poincare/src/constant.cpp b/poincare/src/constant.cpp index 40729429c..eb53a14d9 100644 --- a/poincare/src/constant.cpp +++ b/poincare/src/constant.cpp @@ -50,9 +50,9 @@ CodePoint ConstantNode::codePoint() const { return result; } -int ConstantNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const { +int ConstantNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const { if (!ascending) { - return e->simplificationOrderSameType(this, true, canBeInterrupted); + return e->simplificationOrderSameType(this, true, canBeInterrupted, ignoreParentheses); } assert(type() == e->type()); return rankOfConstant(codePoint()) - rankOfConstant(static_cast(e)->codePoint()); diff --git a/poincare/src/decimal.cpp b/poincare/src/decimal.cpp index da17e993d..82330919d 100644 --- a/poincare/src/decimal.cpp +++ b/poincare/src/decimal.cpp @@ -11,12 +11,10 @@ #include #include #include +#include namespace Poincare { -static inline int maxInt(int x, int y) { return x > y ? x : y; } -static inline int minInt(int x, int y) { return x < y ? x : y; } - void removeZeroAtTheEnd(Integer * i, int minimalNumbersOfDigits = -1) { /* Remove the zeroes at the end of an integer, respecting the minimum number * of digits asked for. @@ -87,9 +85,9 @@ Expression DecimalNode::setSign(Sign s, ReductionContext reductionContext) { return Decimal(this).setSign(s); } -int DecimalNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const { +int DecimalNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const { if (!ascending) { - return e->simplificationOrderSameType(this, true, canBeInterrupted); + return e->simplificationOrderSameType(this, true, canBeInterrupted, ignoreParentheses); } assert(e->type() == Type::Decimal); const DecimalNode * other = static_cast(e); @@ -204,7 +202,7 @@ int DecimalNode::convertToText(char * buffer, int bufferSize, Preferences::Print // Stop here if m is undef if (strcmp(tempBuffer, Undefined::Name()) == 0) { currentChar += strlcpy(buffer+currentChar, tempBuffer, bufferSize-currentChar); - return minInt(currentChar, bufferSize-1); + return std::min(currentChar, bufferSize-1); } /* We force scientific mode if the number of digits before the dot is superior @@ -216,7 +214,7 @@ int DecimalNode::convertToText(char * buffer, int bufferSize, Preferences::Print if (exponent < 0) { numberOfRequiredDigits = mantissaLength-exponent; } else { - numberOfRequiredDigits = maxInt(mantissaLength, exponent); + numberOfRequiredDigits = std::max(mantissaLength, exponent); } } @@ -269,7 +267,7 @@ int DecimalNode::convertToText(char * buffer, int bufferSize, Preferences::Print assert(UTF8Decoder::CharSizeOfCodePoint('.') == 1); assert(UTF8Decoder::CharSizeOfCodePoint('0') == 1); int deltaCharMantissa = exponent < 0 ? -exponent+1 : 0; - strlcpy(buffer+currentChar+deltaCharMantissa, tempBuffer, maxInt(0, bufferSize-deltaCharMantissa-currentChar)); + strlcpy(buffer+currentChar+deltaCharMantissa, tempBuffer, std::max(0, bufferSize-deltaCharMantissa-currentChar)); if (exponent < 0) { for (int i = 0; i <= -exponent; i++) { buffer[currentChar++] = i == 1 ? '.' : '0'; diff --git a/poincare/src/derivative.cpp b/poincare/src/derivative.cpp index a5e208150..3a9b857a8 100644 --- a/poincare/src/derivative.cpp +++ b/poincare/src/derivative.cpp @@ -56,7 +56,7 @@ Evaluation DerivativeNode::templatedApproximate(Context * context, Preference do { T currentError; T currentResult = riddersApproximation(context, complexFormat, angleUnit, evaluationArgument, h, ¤tError); - h /= 10.0; + h /= (T)10.0; if (std::isnan(currentError) || currentError > error) { continue; } diff --git a/poincare/src/division.cpp b/poincare/src/division.cpp index b7011ffb4..77ff4c825 100644 --- a/poincare/src/division.cpp +++ b/poincare/src/division.cpp @@ -47,7 +47,7 @@ Expression DivisionNode::shallowReduce(ReductionContext reductionContext) { } template Complex DivisionNode::compute(const std::complex c, const std::complex d, Preferences::ComplexFormat complexFormat) { - if (d.real() == 0.0 && d.imag() == 0.0) { + if (d.real() == (T)0.0 && d.imag() == (T)0.0) { return Complex::Undefined(); } return Complex::Builder(c/d); diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index bf6b35f67..f274ab3c6 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -545,6 +545,11 @@ bool Expression::isIdenticalTo(const Expression e) const { return ExpressionNode::SimplificationOrder(node(), e.node(), true, true) == 0; } +bool Expression::isIdenticalToWithoutParentheses(const Expression e) const { + // Same as isIdenticalTo, but ignoring the parentheses. + return ExpressionNode::SimplificationOrder(node(), e.node(), true, true, true) == 0; +} + bool Expression::ParsedExpressionsAreEqual(const char * e0, const char * e1, Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { Expression exp0 = Expression::ParseAndSimplify(e0, context, complexFormat, angleUnit, ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined); Expression exp1 = Expression::ParseAndSimplify(e1, context, complexFormat, angleUnit, ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined); diff --git a/poincare/src/expression_node.cpp b/poincare/src/expression_node.cpp index d1d6d1455..94115d40e 100644 --- a/poincare/src/expression_node.cpp +++ b/poincare/src/expression_node.cpp @@ -67,30 +67,42 @@ float ExpressionNode::characteristicXRange(Context * context, Preferences::Angle return range; } -int ExpressionNode::SimplificationOrder(const ExpressionNode * e1, const ExpressionNode * e2, bool ascending, bool canBeInterrupted) { - if (e1->type() > e2->type()) { +int ExpressionNode::SimplificationOrder(const ExpressionNode * e1, const ExpressionNode * e2, bool ascending, bool canBeInterrupted, bool ignoreParentheses) { + // Depending on ignoreParentheses, check if e1 or e2 are parenthesis + ExpressionNode::Type type1 = e1->type(); + if (ignoreParentheses && type1 == Type::Parenthesis) { + if (canBeInterrupted && Expression::ShouldStopProcessing()) { + return -1; + } + return SimplificationOrder(e1->childAtIndex(0), e2, ascending, canBeInterrupted, ignoreParentheses); + } + ExpressionNode::Type type2 = e2->type(); + if (ignoreParentheses && type2 == Type::Parenthesis) { + return SimplificationOrder(e1, e2->childAtIndex(0), ascending, canBeInterrupted, ignoreParentheses); + } + if (type1 > type2) { if (canBeInterrupted && Expression::ShouldStopProcessing()) { return 1; } - return -(e2->simplificationOrderGreaterType(e1, ascending, canBeInterrupted)); - } else if (e1->type() == e2->type()) { - return e1->simplificationOrderSameType(e2, ascending, canBeInterrupted); + return -(e2->simplificationOrderGreaterType(e1, ascending, canBeInterrupted, ignoreParentheses)); + } else if (type1 == type2) { + return e1->simplificationOrderSameType(e2, ascending, canBeInterrupted, ignoreParentheses); } else { if (canBeInterrupted && Expression::ShouldStopProcessing()) { return -1; } - return e1->simplificationOrderGreaterType(e2, ascending, canBeInterrupted); + return e1->simplificationOrderGreaterType(e2, ascending, canBeInterrupted, ignoreParentheses); } } -int ExpressionNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const { +int ExpressionNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const { int index = 0; for (ExpressionNode * c : children()) { // The NULL node is the least node type. if (e->numberOfChildren() <= index) { return 1; } - int childIOrder = SimplificationOrder(c, e->childAtIndex(index), ascending, canBeInterrupted); + int childIOrder = SimplificationOrder(c, e->childAtIndex(index), ascending, canBeInterrupted, ignoreParentheses); if (childIOrder != 0) { return childIOrder; } diff --git a/poincare/src/float.cpp b/poincare/src/float.cpp index 3052747ed..cdfd918d7 100644 --- a/poincare/src/float.cpp +++ b/poincare/src/float.cpp @@ -14,9 +14,9 @@ Expression FloatNode::setSign(Sign s, ReductionContext reductionContext) { } template -int FloatNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const { +int FloatNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const { if (!ascending) { - return e->simplificationOrderSameType(this, true, canBeInterrupted); + return e->simplificationOrderSameType(this, true, canBeInterrupted, ignoreParentheses); } assert(e->type() == ExpressionNode::Type::Float); const FloatNode * other = static_cast *>(e); diff --git a/poincare/src/fraction_layout.cpp b/poincare/src/fraction_layout.cpp index bbde8cd6e..43dc8f7c3 100644 --- a/poincare/src/fraction_layout.cpp +++ b/poincare/src/fraction_layout.cpp @@ -5,11 +5,10 @@ #include #include #include +#include namespace Poincare { -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } - void FractionLayoutNode::moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout, bool forSelection) { if (cursor->position() == LayoutCursor::Position::Left && (cursor->layoutNode() == numeratorLayout() @@ -170,7 +169,7 @@ void FractionLayoutNode::didCollapseSiblings(LayoutCursor * cursor) { } KDSize FractionLayoutNode::computeSize() { - KDCoordinate width = maxCoordinate(numeratorLayout()->layoutSize().width(), denominatorLayout()->layoutSize().width()) + KDCoordinate width = std::max(numeratorLayout()->layoutSize().width(), denominatorLayout()->layoutSize().width()) + 2*Metric::FractionAndConjugateHorizontalOverflow+2*Metric::FractionAndConjugateHorizontalMargin; KDCoordinate height = numeratorLayout()->layoutSize().height() + k_fractionLineMargin + k_fractionLineHeight + k_fractionLineMargin diff --git a/poincare/src/grid_layout.cpp b/poincare/src/grid_layout.cpp index f09097d7b..5839d5b0e 100644 --- a/poincare/src/grid_layout.cpp +++ b/poincare/src/grid_layout.cpp @@ -1,11 +1,10 @@ #include #include #include +#include namespace Poincare { -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } - // LayoutNode void GridLayoutNode::moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout, bool forSelection) { @@ -219,7 +218,7 @@ KDCoordinate GridLayoutNode::rowBaseline(int i) { KDCoordinate rowBaseline = 0; int j = 0; for (LayoutNode * l : childrenFromIndex(i*m_numberOfColumns)) { - rowBaseline = maxCoordinate(rowBaseline, l->baseline()); + rowBaseline = std::max(rowBaseline, l->baseline()); j++; if (j >= m_numberOfColumns) { break; @@ -234,8 +233,8 @@ KDCoordinate GridLayoutNode::rowHeight(int i) const { int j = 0; for (LayoutNode * l : const_cast(this)->childrenFromIndex(i*m_numberOfColumns)) { KDCoordinate b = l->baseline(); - underBaseline = maxCoordinate(underBaseline, l->layoutSize().height() - b); - aboveBaseline = maxCoordinate(aboveBaseline, b); + underBaseline = std::max(underBaseline, l->layoutSize().height() - b); + aboveBaseline = std::max(aboveBaseline, b); j++; if (j >= m_numberOfColumns) { break; @@ -259,7 +258,7 @@ KDCoordinate GridLayoutNode::columnWidth(int j) const { int lastIndex = (m_numberOfRows-1)*m_numberOfColumns + j; for (LayoutNode * l : const_cast(this)->childrenFromIndex(j)) { if (childIndex%m_numberOfColumns == j) { - columnWidth = maxCoordinate(columnWidth, l->layoutSize().width()); + columnWidth = std::max(columnWidth, l->layoutSize().width()); if (childIndex >= lastIndex) { break; } diff --git a/poincare/src/horizontal_layout.cpp b/poincare/src/horizontal_layout.cpp index 88fb0bafd..0f743904b 100644 --- a/poincare/src/horizontal_layout.cpp +++ b/poincare/src/horizontal_layout.cpp @@ -3,11 +3,10 @@ #include #include #include +#include namespace Poincare { -static inline KDCoordinate maxCoordinate(KDCoordinate c1, KDCoordinate c2) { return c1 > c2 ? c1 : c2; } - // LayoutNode void HorizontalLayoutNode::moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout, bool forSelection) { @@ -259,8 +258,8 @@ KDSize HorizontalLayoutNode::computeSize() { for (LayoutNode * l : children()) { KDSize childSize = l->layoutSize(); totalWidth += childSize.width(); - maxUnderBaseline = maxCoordinate(maxUnderBaseline, childSize.height() - l->baseline()); - maxAboveBaseline = maxCoordinate(maxAboveBaseline, l->baseline()); + maxUnderBaseline = std::max(maxUnderBaseline, childSize.height() - l->baseline()); + maxAboveBaseline = std::max(maxAboveBaseline, l->baseline()); } return KDSize(totalWidth, maxUnderBaseline + maxAboveBaseline); } @@ -268,7 +267,7 @@ KDSize HorizontalLayoutNode::computeSize() { KDCoordinate HorizontalLayoutNode::computeBaseline() { KDCoordinate result = 0; for (LayoutNode * l : children()) { - result = maxCoordinate(result, l->baseline()); + result = std::max(result, l->baseline()); } return result; } @@ -311,8 +310,8 @@ KDRect HorizontalLayoutNode::relativeSelectionRect(const Layout * selectionStart for (int i = firstSelectedNodeIndex; i <= secondSelectedNodeIndex; i++) { Layout childi = thisLayout.childAtIndex(i); KDSize childSize = childi.layoutSize(); - maxUnderBaseline = maxCoordinate(maxUnderBaseline, childSize.height() - childi.baseline()); - maxAboveBaseline = maxCoordinate(maxAboveBaseline, childi.baseline()); + maxUnderBaseline = std::max(maxUnderBaseline, childSize.height() - childi.baseline()); + maxAboveBaseline = std::max(maxAboveBaseline, childi.baseline()); } return KDRect(KDPoint(selectionXStart, const_cast(this)->baseline() - maxAboveBaseline), KDSize(drawWidth, maxUnderBaseline + maxAboveBaseline)); } diff --git a/poincare/src/integer.cpp b/poincare/src/integer.cpp index d442edce8..b1c197398 100644 --- a/poincare/src/integer.cpp +++ b/poincare/src/integer.cpp @@ -21,10 +21,9 @@ extern "C" { #if POINCARE_INTEGER_LOG #include #endif -namespace Poincare { +#include -static inline int minInt(int x, int y) { return x < y ? x : y; } -static inline int maxInt(int x, int y) { return x > y ? x : y; } +namespace Poincare { /* To compute operations between Integers, we need an array where to store the * result digits. Instead of allocating it on the stack which would eventually @@ -483,7 +482,7 @@ Integer Integer::multiplication(const Integer & a, const Integer & b, bool oneDi return Integer::Overflow(a.m_negative != b.m_negative); } - uint8_t size = minInt(a.numberOfDigits() + b.numberOfDigits(), k_maxNumberOfDigits + oneDigitOverflow); // Enable overflowing of 1 digit + uint8_t size = std::min(a.numberOfDigits() + b.numberOfDigits(), k_maxNumberOfDigits + oneDigitOverflow); // Enable overflowing of 1 digit memset(s_workingBuffer, 0, size*sizeof(native_uint_t)); @@ -552,7 +551,7 @@ Integer Integer::usum(const Integer & a, const Integer & b, bool subtract, bool return Overflow(a.m_negative != b.m_negative); } - uint8_t size = maxInt(a.numberOfDigits(), b.numberOfDigits()); + uint8_t size = std::max(a.numberOfDigits(), b.numberOfDigits()); if (!subtract) { // Addition can overflow size++; @@ -576,7 +575,7 @@ Integer Integer::usum(const Integer & a, const Integer & b, bool subtract, bool carry = (aDigit > result) || (bDigit > result); // There's been an overflow } } - size = minInt(size, k_maxNumberOfDigits+oneDigitOverflow); + size = std::min(size, k_maxNumberOfDigits+oneDigitOverflow); while (size>0 && s_workingBuffer[size-1] == 0) { size--; } @@ -655,7 +654,7 @@ IntegerDivision Integer::udiv(const Integer & numerator, const Integer & denomin // qDigits is a half_native_uint_t array and enable one digit overflow half_native_uint_t * qDigits = reinterpret_cast(s_workingBufferDivision); // The quotient q has at maximum m+1 half digits but we set an extra half digit to 0 to enable to easily convert it from half digits to digits - memset(qDigits, 0, maxInt(m+1+1,2*k_maxNumberOfDigits)*sizeof(half_native_uint_t)); + memset(qDigits, 0, std::max(m+1+1,2*k_maxNumberOfDigits)*sizeof(half_native_uint_t)); // betaMB = B*beta^m Integer betaMB = B.multiplyByPowerOfBase(m); if (Integer::NaturalOrder(A,betaMB) >= 0) { // A >= B*beta^m @@ -666,7 +665,7 @@ IntegerDivision Integer::udiv(const Integer & numerator, const Integer & denomin for (int j = m-1; j >= 0; j--) { native_uint_t qj2 = ((native_uint_t)A.halfDigit(n+j)*base+(native_uint_t)A.halfDigit(n+j-1))/(native_uint_t)B.halfDigit(n-1); // (a[n+j]*beta+a[n+j-1])/b[n-1] half_native_uint_t baseMinus1 = (1 << 16) -1; // beta-1 - qDigits[j] = qj2 < (native_uint_t)baseMinus1 ? (half_native_uint_t)qj2 : baseMinus1; // minInt(qj2, beta -1) + qDigits[j] = qj2 < (native_uint_t)baseMinus1 ? (half_native_uint_t)qj2 : baseMinus1; // std::min(qj2, beta -1) A = Integer::addition(A, multiplication(qDigits[j], B.multiplyByPowerOfBase(j), true), true, true); // A-q[j]*beta^j*B if (A.isNegative()) { Integer betaJM = B.multiplyByPowerOfBase(j); // betaJM = B*beta^j diff --git a/poincare/src/integral.cpp b/poincare/src/integral.cpp index adf6defbf..55641980a 100644 --- a/poincare/src/integral.cpp +++ b/poincare/src/integral.cpp @@ -128,8 +128,8 @@ IntegralNode::DetailedResult IntegralNode::kronrodGaussQuadrature(T a, T b, C T fv1[10]; T fv2[10]; - T center = 0.5 * (a+b); - T halfLength = 0.5 * (b-a); + T center = (T)0.5 * (a+b); + T halfLength = (T)0.5 * (b-a); T absHalfLength = std::fabs(halfLength); DetailedResult errorResult; @@ -163,7 +163,7 @@ IntegralNode::DetailedResult IntegralNode::kronrodGaussQuadrature(T a, T b, C absKronrodIntegral += wKronrod[j] * (std::fabs(fval1) + std::fabs(fval2)); } - T halfKronrodIntegral = 0.5 * kronrodIntegral; + T halfKronrodIntegral = (T)0.5 * kronrodIntegral; T kronrodIntegralDifference = wKronrod[10] * std::fabs(fCenter - halfKronrodIntegral); for (int j = 0; j < 10; j++) { kronrodIntegralDifference += wKronrod[j] * (std::fabs(fv1[j] - halfKronrodIntegral) + std::fabs(fv2[j] - halfKronrodIntegral)); @@ -176,7 +176,7 @@ IntegralNode::DetailedResult IntegralNode::kronrodGaussQuadrature(T a, T b, C T errorCoefficient = std::pow((T)(200*absError/kronrodIntegralDifference), (T)1.5); absError = 1 > errorCoefficient ? kronrodIntegralDifference * errorCoefficient : kronrodIntegralDifference; } - if (absKronrodIntegral > max/(50.0 * epsilon)) { + if (absKronrodIntegral > max/((T)50.0 * epsilon)) { T minError = epsilon * 50 * absKronrodIntegral; absError = absError > minError ? absError : minError; } diff --git a/poincare/src/integral_layout.cpp b/poincare/src/integral_layout.cpp index ca5416202..b9524c489 100644 --- a/poincare/src/integral_layout.cpp +++ b/poincare/src/integral_layout.cpp @@ -4,11 +4,10 @@ #include #include #include +#include namespace Poincare { -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } - const uint8_t topSymbolPixel[IntegralLayoutNode::k_symbolHeight][IntegralLayoutNode::k_symbolWidth] = { {0x00, 0x00, 0xFF, 0xFF}, {0xFF, 0xFF, 0x00, 0xFF}, @@ -215,14 +214,14 @@ KDSize IntegralLayoutNode::computeSize() { KDSize differentialSize = differentialLayout()->layoutSize(); KDSize lowerBoundSize = lowerBoundLayout()->layoutSize(); KDSize upperBoundSize = upperBoundLayout()->layoutSize(); - KDCoordinate width = k_symbolWidth+k_lineThickness+k_boundWidthMargin+maxCoordinate(lowerBoundSize.width(), upperBoundSize.width())+k_integrandWidthMargin+integrandSize.width()+2*k_differentialWidthMargin+dSize.width()+differentialSize.width(); + KDCoordinate width = k_symbolWidth+k_lineThickness+k_boundWidthMargin+std::max(lowerBoundSize.width(), upperBoundSize.width())+k_integrandWidthMargin+integrandSize.width()+2*k_differentialWidthMargin+dSize.width()+differentialSize.width(); KDCoordinate baseline = computeBaseline(); - KDCoordinate height = baseline + k_integrandHeigthMargin+maxCoordinate(integrandSize.height()-integrandLayout()->baseline(), differentialSize.height()-differentialLayout()->baseline())+lowerBoundSize.height(); + KDCoordinate height = baseline + k_integrandHeigthMargin+std::max(integrandSize.height()-integrandLayout()->baseline(), differentialSize.height()-differentialLayout()->baseline())+lowerBoundSize.height(); return KDSize(width, height); } KDCoordinate IntegralLayoutNode::computeBaseline() { - return upperBoundLayout()->layoutSize().height() + k_integrandHeigthMargin + maxCoordinate(integrandLayout()->baseline(), differentialLayout()->baseline()); + return upperBoundLayout()->layoutSize().height() + k_integrandHeigthMargin + std::max(integrandLayout()->baseline(), differentialLayout()->baseline()); } KDPoint IntegralLayoutNode::positionOfChild(LayoutNode * child) { @@ -237,7 +236,7 @@ KDPoint IntegralLayoutNode::positionOfChild(LayoutNode * child) { x = k_symbolWidth+k_lineThickness+k_boundWidthMargin;; y = 0; } else if (child == integrandLayout()) { - x = k_symbolWidth +k_lineThickness+ k_boundWidthMargin+maxCoordinate(lowerBoundSize.width(), upperBoundSize.width())+k_integrandWidthMargin; + x = k_symbolWidth +k_lineThickness+ k_boundWidthMargin+std::max(lowerBoundSize.width(), upperBoundSize.width())+k_integrandWidthMargin; y = computeBaseline()-integrandLayout()->baseline(); } else if (child == differentialLayout()) { x = computeSize().width() - k_differentialWidthMargin - differentialLayout()->layoutSize().width(); @@ -252,7 +251,7 @@ void IntegralLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expressionCo KDSize integrandSize = integrandLayout()->layoutSize(); KDSize differentialSize = differentialLayout()->layoutSize(); KDSize upperBoundSize = upperBoundLayout()->layoutSize(); - KDCoordinate centralArgumentHeight = maxCoordinate(integrandLayout()->baseline(), differentialLayout()->baseline()) + maxCoordinate(integrandSize.height()-integrandLayout()->baseline(), differentialSize.height()-differentialLayout()->baseline()); + KDCoordinate centralArgumentHeight = std::max(integrandLayout()->baseline(), differentialLayout()->baseline()) + std::max(integrandSize.height()-integrandLayout()->baseline(), differentialSize.height()-differentialLayout()->baseline()); KDColor workingBuffer[k_symbolWidth*k_symbolHeight]; diff --git a/poincare/src/layout_cursor.cpp b/poincare/src/layout_cursor.cpp index b4272aac3..e62be6e29 100644 --- a/poincare/src/layout_cursor.cpp +++ b/poincare/src/layout_cursor.cpp @@ -10,15 +10,13 @@ #include #include #include -#include #include +#include namespace Poincare { /* Getters and setters */ -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } - KDCoordinate LayoutCursor::cursorHeightWithoutSelection() { KDCoordinate height = layoutHeight(); return height == 0 ? k_cursorHeight : height; @@ -36,7 +34,7 @@ KDCoordinate LayoutCursor::baselineWithoutSelection() { if (m_layout.hasChild(equivalentLayout)) { return equivalentLayout.baseline(); } else if (m_layout.hasSibling(equivalentLayout)) { - return maxCoordinate(layoutBaseline, equivalentLayout.baseline()); + return std::max(layoutBaseline, equivalentLayout.baseline()); } return layoutBaseline; } @@ -262,8 +260,8 @@ KDCoordinate LayoutCursor::layoutHeight() { KDCoordinate equivalentLayoutHeight = equivalentLayout.layoutSize().height(); KDCoordinate pointedLayoutBaseline = m_layout.baseline(); KDCoordinate equivalentLayoutBaseline = equivalentLayout.baseline(); - return maxCoordinate(pointedLayoutBaseline, equivalentLayoutBaseline) - + maxCoordinate(pointedLayoutHeight - pointedLayoutBaseline, equivalentLayoutHeight - equivalentLayoutBaseline); + return std::max(pointedLayoutBaseline, equivalentLayoutBaseline) + + std::max(pointedLayoutHeight - pointedLayoutBaseline, equivalentLayoutHeight - equivalentLayoutBaseline); } return pointedLayoutHeight; } diff --git a/poincare/src/logarithm.cpp b/poincare/src/logarithm.cpp index b6297c1e3..803dfc18d 100644 --- a/poincare/src/logarithm.cpp +++ b/poincare/src/logarithm.cpp @@ -279,7 +279,7 @@ Expression Logarithm::simpleShallowReduce(Context * context, Preferences::Comple if (logDenominator.imag() != 0.0f || logDenominator.real() == 0.0f) { result = Undefined::Builder(); } - isNegative = logDenominator.real() > 0.0; + isNegative = logDenominator.real() > 0.0f; result = result.isUninitialized() ? Infinity::Builder(isNegative) : result; replaceWithInPlace(result); return result; diff --git a/poincare/src/matrix.cpp b/poincare/src/matrix.cpp index e34393aef..b310b1ef0 100644 --- a/poincare/src/matrix.cpp +++ b/poincare/src/matrix.cpp @@ -15,11 +15,10 @@ #include #include #include +#include namespace Poincare { -static inline int minInt(int x, int y) { return x < y ? x : y; } - bool MatrixNode::hasMatrixChild(Context * context) const { for (ExpressionNode * c : children()) { if (Expression(c).deepIsMatrix(context)) { @@ -93,7 +92,7 @@ int MatrixNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloat } } currentChar += SerializationHelper::CodePoint(buffer + currentChar, bufferSize - currentChar, ']'); - return minInt(currentChar, bufferSize-1); + return std::min(currentChar, bufferSize-1); } template @@ -270,7 +269,7 @@ void Matrix::ArrayRowCanonize(T * array, int numberOfRows, int numberOfColumns, // No non-null coefficient in this column, skip k++; // Update determinant: det *= 0 - if (determinant) { *determinant *= 0.0; } + if (determinant) { *determinant *= (T)0.0; } } else { // Swap row h and iPivot if (iPivot != h) { @@ -281,7 +280,7 @@ void Matrix::ArrayRowCanonize(T * array, int numberOfRows, int numberOfColumns, array[h*numberOfColumns+col] = temp; } // Update determinant: det *= -1 - if (determinant) { *determinant *= -1.0; } + if (determinant) { *determinant *= (T)-1.0; } } // Set to 1 array[h][k] by linear combination T divisor = array[h*numberOfColumns+k]; @@ -378,17 +377,17 @@ Expression Matrix::determinant(ExpressionNode::ReductionContext reductionContext Expression g = m.matrixChild(2,0); Expression h = m.matrixChild(2,1); Expression i = m.matrixChild(2,2); - constexpr int additionChildrenCount = 6; - Expression additionChildren[additionChildrenCount] = { + Tuple children = { Multiplication::Builder(a.clone(), e.clone(), i.clone()), Multiplication::Builder(b.clone(), f.clone(), g.clone()), Multiplication::Builder(c.clone(), d.clone(), h.clone()), Multiplication::Builder(Rational::Builder(-1), c, e, g), Multiplication::Builder(Rational::Builder(-1), b, d, i), - Multiplication::Builder(Rational::Builder(-1), a, f, h)}; - Expression result = Addition::Builder(additionChildren, additionChildrenCount); - for (int i = 0; i < additionChildrenCount; i++) { - additionChildren[i].shallowReduce(reductionContext); + Multiplication::Builder(Rational::Builder(-1), a, f, h) + }; + Expression result = Addition::Builder(children); + for (Expression child : children) { + child.shallowReduce(reductionContext); } return result; } diff --git a/poincare/src/matrix_layout.cpp b/poincare/src/matrix_layout.cpp index a82ac00af..bb1b05a01 100644 --- a/poincare/src/matrix_layout.cpp +++ b/poincare/src/matrix_layout.cpp @@ -4,11 +4,10 @@ #include #include #include +#include namespace Poincare { -static inline int minInt(int x, int y) { return x < y ? x : y; } - // MatrixLayoutNode void MatrixLayoutNode::addGreySquares() { @@ -164,7 +163,7 @@ int MatrixLayoutNode::serialize(char * buffer, int bufferSize, Preferences::Prin // Write the final closing bracket numberOfChar += SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, ']'); - return minInt(numberOfChar, bufferSize-1); + return std::min(numberOfChar, bufferSize-1); } // Protected @@ -331,7 +330,7 @@ void MatrixLayoutNode::didReplaceChildAtIndex(int index, LayoutCursor * cursor, } MatrixLayout MatrixLayout::Builder(Layout l1, Layout l2, Layout l3, Layout l4) { - MatrixLayout m = TreeHandle::NAryBuilder(ArrayBuilder(l1,l2,l3,l4).array(), 4); + MatrixLayout m = TreeHandle::NAryBuilder({l1, l2, l3, l4}); m.setDimensions(2, 2); return m; } diff --git a/poincare/src/multiplication.cpp b/poincare/src/multiplication.cpp index f0767a8c5..62b00da2b 100644 --- a/poincare/src/multiplication.cpp +++ b/poincare/src/multiplication.cpp @@ -20,6 +20,7 @@ #include #include #include +#include namespace Poincare { @@ -91,8 +92,6 @@ Expression MultiplicationNode::setSign(Sign s, ReductionContext reductionContext return Multiplication(this).setSign(s, reductionContext); } -static inline int maxInt(int x, int y) { return x > y ? x : y; } - /* Operative symbol between two expressions depends on the layout shape on the * left and the right of the operator: * @@ -185,7 +184,7 @@ CodePoint MultiplicationNode::operatorSymbol() const { for (int i = 0; i < numberOfChildren() - 1; i++) { /* The operator symbol must be the same for all operands of the multiplication. * If one operator has to be '×', they will all be '×'. Idem for '·'. */ - sign = maxInt(sign, operatorSymbolBetween(childAtIndex(i)->rightLayoutShape(), childAtIndex(i+1)->leftLayoutShape())); + sign = std::max(sign, operatorSymbolBetween(childAtIndex(i)->rightLayoutShape(), childAtIndex(i+1)->leftLayoutShape())); } } else { switch(preferences->symbolofMultiplication()){ diff --git a/poincare/src/n_ary_expression.cpp b/poincare/src/n_ary_expression.cpp index 495529416..917877808 100644 --- a/poincare/src/n_ary_expression.cpp +++ b/poincare/src/n_ary_expression.cpp @@ -61,7 +61,7 @@ Expression NAryExpressionNode::squashUnaryHierarchyInPlace() { // Private -int NAryExpressionNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const { +int NAryExpressionNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const { int m = numberOfChildren(); int n = e->numberOfChildren(); for (int i = 1; i <= m; i++) { @@ -69,7 +69,7 @@ int NAryExpressionNode::simplificationOrderSameType(const ExpressionNode * e, bo if (n < i) { return 1; } - int order = SimplificationOrder(childAtIndex(m-i), e->childAtIndex(n-i), ascending, canBeInterrupted); + int order = SimplificationOrder(childAtIndex(m-i), e->childAtIndex(n-i), ascending, canBeInterrupted, ignoreParentheses); if (order != 0) { return order; } @@ -81,13 +81,13 @@ int NAryExpressionNode::simplificationOrderSameType(const ExpressionNode * e, bo return 0; } -int NAryExpressionNode::simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const { +int NAryExpressionNode::simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const { int m = numberOfChildren(); if (m == 0) { return -1; } /* Compare e to last term of hierarchy. */ - int order = SimplificationOrder(childAtIndex(m-1), e, ascending, canBeInterrupted); + int order = SimplificationOrder(childAtIndex(m-1), e, ascending, canBeInterrupted, ignoreParentheses); if (order != 0) { return order; } diff --git a/poincare/src/normal_distribution.cpp b/poincare/src/normal_distribution.cpp index 0d27f41a3..ba62b1dca 100644 --- a/poincare/src/normal_distribution.cpp +++ b/poincare/src/normal_distribution.cpp @@ -5,6 +5,8 @@ #include #include +#define M_SQRT_2PI 2.506628274631000502415765284811 + namespace Poincare { template @@ -13,7 +15,7 @@ T NormalDistribution::EvaluateAtAbscissa(T x, T mu, T sigma) { return NAN; } const float xMinusMuOverVar = (x - mu)/sigma; - return ((T)1.0)/(std::fabs(sigma) * std::sqrt(((T)2.0) * M_PI)) * std::exp(-((T)0.5) * xMinusMuOverVar * xMinusMuOverVar); + return ((T)1.0)/(std::fabs(sigma) * (T)M_SQRT_2PI) * std::exp(-((T)0.5) * xMinusMuOverVar * xMinusMuOverVar); } template @@ -95,7 +97,7 @@ T NormalDistribution::StandardNormalCumulativeDistributiveFunctionAtAbscissa(T a if (abscissa < (T)0.0) { return ((T)1.0) - StandardNormalCumulativeDistributiveFunctionAtAbscissa(-abscissa); } - return ((T)0.5) + ((T)0.5) * std::erf(abscissa/std::sqrt(((T)2.0))); + return ((T)0.5) + ((T)0.5) * std::erf(abscissa/(T)M_SQRT2); } template @@ -113,7 +115,7 @@ T NormalDistribution::StandardNormalCumulativeDistributiveInverseForProbability( if (probability < (T)0.5) { return -StandardNormalCumulativeDistributiveInverseForProbability(((T)1.0)-probability); } - return std::sqrt((T)2.0) * erfInv(((T)2.0) * probability - (T)1.0); + return (T)M_SQRT2 * erfInv(((T)2.0) * probability - (T)1.0); } template float NormalDistribution::EvaluateAtAbscissa(float, float, float); diff --git a/poincare/src/nth_root_layout.cpp b/poincare/src/nth_root_layout.cpp index 807c15449..fac507a43 100644 --- a/poincare/src/nth_root_layout.cpp +++ b/poincare/src/nth_root_layout.cpp @@ -4,10 +4,12 @@ #include #include #include +#include namespace Poincare { -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } +constexpr KDCoordinate NthRootLayoutNode::k_leftRadixHeight; +constexpr KDCoordinate NthRootLayoutNode::k_leftRadixWidth; const uint8_t radixPixel[NthRootLayoutNode::k_leftRadixHeight][NthRootLayoutNode::k_leftRadixWidth] = { {0x51, 0xCC, 0xFF, 0xFF, 0xFF}, @@ -180,7 +182,7 @@ KDSize NthRootLayoutNode::computeSize() { } KDCoordinate NthRootLayoutNode::computeBaseline() { - return maxCoordinate( + return std::max( radicandLayout()->baseline() + k_radixLineThickness + k_heightMargin, adjustedIndexSize().height()); } @@ -204,7 +206,7 @@ KDPoint NthRootLayoutNode::positionOfChild(LayoutNode * child) { KDSize NthRootLayoutNode::adjustedIndexSize() { return indexLayout() == nullptr ? KDSize(k_leftRadixWidth, 0) : - KDSize(maxCoordinate(k_leftRadixWidth, indexLayout()->layoutSize().width()), indexLayout()->layoutSize().height()); + KDSize(std::max(k_leftRadixWidth, indexLayout()->layoutSize().width()), indexLayout()->layoutSize().height()); } void NthRootLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor, Layout * selectionStart, Layout * selectionEnd, KDColor selectionColor) { diff --git a/poincare/src/number.cpp b/poincare/src/number.cpp index 0136cb545..42c1cac17 100644 --- a/poincare/src/number.cpp +++ b/poincare/src/number.cpp @@ -72,7 +72,7 @@ Number Number::DecimalNumber(T f) { return Undefined::Builder(); } if (std::isinf(f)) { - return Infinity::Builder(f < 0.0); + return Infinity::Builder(f < (T)0.0); } return Decimal::Builder(f); } diff --git a/poincare/src/parenthesis.cpp b/poincare/src/parenthesis.cpp index 81b7fddb7..ca514b079 100644 --- a/poincare/src/parenthesis.cpp +++ b/poincare/src/parenthesis.cpp @@ -25,7 +25,6 @@ Evaluation ParenthesisNode::templatedApproximate(Context * context, Preferenc return childAtIndex(0)->approximate(T(), context, complexFormat, angleUnit); } - 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 1f7d63d90..2b8873bd1 100644 --- a/poincare/src/parsing/parser.cpp +++ b/poincare/src/parsing/parser.cpp @@ -1,11 +1,10 @@ #include "parser.h" #include #include +#include namespace Poincare { -static inline Token::Type maxToken(Token::Type x, Token::Type y) { return ((int)x > (int) y ? x : y); } - constexpr const Expression::FunctionHelper * Parser::s_reservedFunctions[]; Expression Parser::parse() { @@ -185,7 +184,7 @@ void Parser::parseEmpty(Expression & leftHandSide, Token::Type stoppingType) { void Parser::parseMinus(Expression & leftHandSide, Token::Type stoppingType) { if (leftHandSide.isUninitialized()) { - Expression rightHandSide = parseUntil(maxToken(stoppingType, Token::Minus)); + Expression rightHandSide = parseUntil(std::max(stoppingType, Token::Minus)); if (m_status != Status::Progress) { return; } diff --git a/poincare/src/power.cpp b/poincare/src/power.cpp index fa7e3c755..da0579f72 100644 --- a/poincare/src/power.cpp +++ b/poincare/src/power.cpp @@ -136,7 +136,7 @@ Complex PowerNode::computeNotPrincipalRealRootOfRationalPow(const std::comple * where the principal root is real as these cases are handled generically * later (for instance 1232^(1/8) which has a real principal root is not * handled here). */ - if (c.imag() == 0 && std::pow((T)-1.0, q) < 0.0) { + if (c.imag() == (T)0.0 && std::pow((T)-1.0, q) < (T)0.0) { /* If c real and q odd integer (q odd if (-1)^q = -1), a real root does * exist (which is not necessarily the principal root)! * For q even integer, a real root does not necessarily exist (example: @@ -148,7 +148,7 @@ Complex PowerNode::computeNotPrincipalRealRootOfRationalPow(const std::comple /* As q is odd, c^(p/q) = (sign(c)^(1/q))^p * |c|^(p/q) * = sign(c)^p * |c|^(p/q) * = -|c|^(p/q) iff c < 0 and p odd */ - return c.real() < 0 && std::pow((T)-1.0, p) < 0.0 ? Complex::Builder(-absCPowD.stdComplex()) : absCPowD; + return c.real() < (T)0.0 && std::pow((T)-1.0, p) < (T)0.0 ? Complex::Builder(-absCPowD.stdComplex()) : absCPowD; } return Complex::Undefined(); } @@ -156,7 +156,7 @@ Complex PowerNode::computeNotPrincipalRealRootOfRationalPow(const std::comple template Complex PowerNode::compute(const std::complex c, const std::complex d, Preferences::ComplexFormat complexFormat) { std::complex result; - if (c.imag() == 0.0 && d.imag() == 0.0 && c.real() != 0.0 && (c.real() > 0.0 || std::round(d.real()) == d.real())) { + if (c.imag() == (T)0.0 && d.imag() == (T)0.0 && c.real() != (T)0.0 && (c.real() > (T)0.0 || std::round(d.real()) == d.real())) { /* pow: (R+, R) -> R+ (2^1.3 ~ 2.46) * pow: (R-, N) -> R+ ((-2)^3 = -8) * In these cases we rather use std::pow(double, double) because: @@ -228,23 +228,23 @@ Expression PowerNode::shallowBeautify(ReductionContext reductionContext) { return Power(this).shallowBeautify(reductionContext); } -int PowerNode::simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const { - int baseComparison = SimplificationOrder(childAtIndex(0), e, ascending, canBeInterrupted); +int PowerNode::simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const { + int baseComparison = SimplificationOrder(childAtIndex(0), e, ascending, canBeInterrupted, ignoreParentheses); if (baseComparison != 0) { return baseComparison; } Rational one = Rational::Builder(1); - return SimplificationOrder(childAtIndex(1), one.node(), ascending, canBeInterrupted); + return SimplificationOrder(childAtIndex(1), one.node(), ascending, canBeInterrupted, ignoreParentheses); } -int PowerNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const { +int PowerNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const { assert(e->numberOfChildren() > 0); - int baseComparison = SimplificationOrder(childAtIndex(0), e->childAtIndex(0), ascending, canBeInterrupted); + int baseComparison = SimplificationOrder(childAtIndex(0), e->childAtIndex(0), ascending, canBeInterrupted, ignoreParentheses); if (baseComparison != 0) { return baseComparison; } assert(e->numberOfChildren() > 1); - return SimplificationOrder(childAtIndex(1), e->childAtIndex(1), ascending, canBeInterrupted); + return SimplificationOrder(childAtIndex(1), e->childAtIndex(1), ascending, canBeInterrupted, ignoreParentheses); } Expression PowerNode::denominator(ReductionContext reductionContext) const { diff --git a/poincare/src/prediction_interval.cpp b/poincare/src/prediction_interval.cpp index f3bad4750..0893818e6 100644 --- a/poincare/src/prediction_interval.cpp +++ b/poincare/src/prediction_interval.cpp @@ -40,8 +40,8 @@ Evaluation PredictionIntervalNode::templatedApproximate(Context * context, Pr return Complex::RealUndefined(); } 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)); + operands[0] = std::complex(p - (T)1.96*std::sqrt(p*((T)1.0-p))/std::sqrt(n)); + operands[1] = std::complex(p + (T)1.96*std::sqrt(p*((T)1.0-p))/std::sqrt(n)); return MatrixComplex::Builder(operands, 1, 2); } diff --git a/poincare/src/print_float.cpp b/poincare/src/print_float.cpp index c34f64420..0aa8e66fc 100644 --- a/poincare/src/print_float.cpp +++ b/poincare/src/print_float.cpp @@ -15,10 +15,11 @@ extern "C" { #include } #include +#include namespace Poincare { -static inline int minInt(int x, int y) { return x < y ? x : y; } +constexpr int PrintFloat::Long::k_maxNumberOfCharsForDigit; PrintFloat::Long::Long(int64_t i) : m_negative(i < 0) @@ -79,7 +80,7 @@ int PrintFloat::Long::serialize(char * buffer, int bufferSize) const { * terminating char. */ return wantedNumberOfChars; } - numberOfChars+= PrintInt::Right(m_digits[1], buffer + numberOfChars, minInt(k_maxNumberOfCharsForDigit, bufferSize - numberOfChars - 1)); + numberOfChars+= PrintInt::Right(m_digits[1], buffer + numberOfChars, std::min(k_maxNumberOfCharsForDigit, bufferSize - numberOfChars - 1)); } else { numberOfChars+= PrintInt::Left(m_digits[1], buffer + numberOfChars, bufferSize - numberOfChars - 1); } @@ -167,7 +168,7 @@ PrintFloat::TextLengths PrintFloat::ConvertFloatToTextPrivate(T f, char * buffer assert(numberOfSignificantDigits > 0); assert(bufferSize > 0); assert(glyphLength > 0 && glyphLength <= k_maxFloatGlyphLength); - int availableCharLength = minInt(bufferSize-1, glyphLength); + int availableCharLength = std::min(bufferSize-1, glyphLength); TextLengths exceptionResult = {.CharLength = bufferSize, .GlyphLength = glyphLength+1}; //TODO: accelerate for f between 0 and 10 ? if (std::isinf(f)) { @@ -238,7 +239,7 @@ PrintFloat::TextLengths PrintFloat::ConvertFloatToTextPrivate(T f, char * buffer // Correct the number of digits in mantissa after rounding if (IEEE754::exponentBase10(mantissa) >= numberOfSignificantDigits) { - mantissa = mantissa/10.0; + mantissa = mantissa / (T)10.0; } // Number of chars for the mantissa diff --git a/poincare/src/product_layout.cpp b/poincare/src/product_layout.cpp index 6333c6735..190916813 100644 --- a/poincare/src/product_layout.cpp +++ b/poincare/src/product_layout.cpp @@ -1,11 +1,10 @@ #include #include #include +#include namespace Poincare { -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } - int ProductLayoutNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { return SequenceLayoutNode::writeDerivedClassInBuffer("product", buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits); } @@ -16,14 +15,14 @@ void ProductLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expressionCol KDSize lowerBoundNEqualsSize = lowerBoundSizeWithVariableEquals(); // Render the Product symbol. - ctx->fillRect(KDRect(p.x() + maxCoordinate(maxCoordinate(0, (upperBoundSize.width()-k_symbolWidth)/2), (lowerBoundNEqualsSize.width()-k_symbolWidth)/2), - p.y() + maxCoordinate(upperBoundSize.height()+k_boundHeightMargin, argumentLayout()->baseline()-(k_symbolHeight+1)/2), + ctx->fillRect(KDRect(p.x() + std::max(std::max(0, (upperBoundSize.width()-k_symbolWidth)/2), (lowerBoundNEqualsSize.width()-k_symbolWidth)/2), + p.y() + std::max(upperBoundSize.height()+k_boundHeightMargin, argumentLayout()->baseline()-(k_symbolHeight+1)/2), k_lineThickness, k_symbolHeight), expressionColor); - ctx->fillRect(KDRect(p.x() + maxCoordinate(maxCoordinate(0, (upperBoundSize.width()-k_symbolWidth)/2), (lowerBoundNEqualsSize.width()-k_symbolWidth)/2), - p.y() + maxCoordinate(upperBoundSize.height()+k_boundHeightMargin, argumentLayout()->baseline()-(k_symbolHeight+1)/2), + ctx->fillRect(KDRect(p.x() + std::max(std::max(0, (upperBoundSize.width()-k_symbolWidth)/2), (lowerBoundNEqualsSize.width()-k_symbolWidth)/2), + p.y() + std::max(upperBoundSize.height()+k_boundHeightMargin, argumentLayout()->baseline()-(k_symbolHeight+1)/2), k_symbolWidth, k_lineThickness), expressionColor); - ctx->fillRect(KDRect(p.x() + maxCoordinate(maxCoordinate(0, (upperBoundSize.width()-k_symbolWidth)/2), (lowerBoundNEqualsSize.width()-k_symbolWidth)/2)+k_symbolWidth, - p.y() + maxCoordinate(upperBoundSize.height()+k_boundHeightMargin, argumentLayout()->baseline()-(k_symbolHeight+1)/2), + ctx->fillRect(KDRect(p.x() + std::max(std::max(0, (upperBoundSize.width()-k_symbolWidth)/2), (lowerBoundNEqualsSize.width()-k_symbolWidth)/2)+k_symbolWidth, + p.y() + std::max(upperBoundSize.height()+k_boundHeightMargin, argumentLayout()->baseline()-(k_symbolHeight+1)/2), k_lineThickness, k_symbolHeight), expressionColor); // Render the "n=" and the parentheses. diff --git a/poincare/src/randint.cpp b/poincare/src/randint.cpp index 148aae3bd..52d15e7f9 100644 --- a/poincare/src/randint.cpp +++ b/poincare/src/randint.cpp @@ -49,10 +49,10 @@ template Evaluation RandintNode::templateApproximate(Context * c if (std::isnan(a) || std::isnan(b) || std::isinf(a) || std::isinf(b) || a > b || a != (int)a || b != (int)b - || (Expression::Epsilon()*(b+1.0-a) > 1.0)) { + || (Expression::Epsilon()*(b+(T)1.0-a) > (T)1.0)) { return Complex::RealUndefined(); } - T result = std::floor(Random::random()*(b+1.0-a)+a); + T result = std::floor(Random::random()*(b+(T)1.0-a)+a); return Complex::Builder(result); } diff --git a/poincare/src/rational.cpp b/poincare/src/rational.cpp index b04ed48a9..58f07cc3e 100644 --- a/poincare/src/rational.cpp +++ b/poincare/src/rational.cpp @@ -126,9 +126,9 @@ int RationalNode::NaturalOrder(const RationalNode * i, const RationalNode * j) { return Integer::NaturalOrder(i1, i2); } -int RationalNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const { +int RationalNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const { if (!ascending) { - return e->simplificationOrderSameType(this, true, canBeInterrupted); + return e->simplificationOrderSameType(this, true, canBeInterrupted, ignoreParentheses); } assert(e->type() == ExpressionNode::Type::Rational); const RationalNode * other = static_cast(e); diff --git a/poincare/src/sequence_layout.cpp b/poincare/src/sequence_layout.cpp index 9ada97de5..248b76e63 100644 --- a/poincare/src/sequence_layout.cpp +++ b/poincare/src/sequence_layout.cpp @@ -4,10 +4,11 @@ #include #include #include +#include namespace Poincare { -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } +constexpr KDCoordinate SequenceLayoutNode::k_symbolWidth; void SequenceLayoutNode::moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout, bool forSelection) { if (cursor->layoutNode() == upperBoundLayout()) @@ -160,7 +161,7 @@ KDSize SequenceLayoutNode::lowerBoundSizeWithVariableEquals() { KDSize equalSize = k_font->stringSize(k_equal); return KDSize( variableSize.width() + equalSize.width() + lowerBoundSize.width(), - subscriptBaseline() + maxCoordinate(maxCoordinate(variableSize.height() - variableLayout()->baseline(), lowerBoundSize.height() - lowerBoundLayout()->baseline()), equalSize.height()/2)); + subscriptBaseline() + std::max(std::max(variableSize.height() - variableLayout()->baseline(), lowerBoundSize.height() - lowerBoundLayout()->baseline()), equalSize.height()/2)); } KDSize SequenceLayoutNode::computeSize() { @@ -171,13 +172,13 @@ KDSize SequenceLayoutNode::computeSize() { argumentSize.width() + 2*ParenthesisLayoutNode::ParenthesisWidth(), ParenthesisLayoutNode::HeightGivenChildHeight(argumentSize.height())); KDSize result = KDSize( - maxCoordinate(maxCoordinate(k_symbolWidth, totalLowerBoundSize.width()), upperBoundSize.width())+k_argumentWidthMargin+argumentSizeWithParentheses.width(), - baseline() + maxCoordinate(k_symbolHeight/2+k_boundHeightMargin+totalLowerBoundSize.height(), argumentSizeWithParentheses.height() - argumentLayout()->baseline())); + std::max(std::max(k_symbolWidth, totalLowerBoundSize.width()), upperBoundSize.width())+k_argumentWidthMargin+argumentSizeWithParentheses.width(), + baseline() + std::max(k_symbolHeight/2+k_boundHeightMargin+totalLowerBoundSize.height(), argumentSizeWithParentheses.height() - argumentLayout()->baseline())); return result; } KDCoordinate SequenceLayoutNode::computeBaseline() { - return maxCoordinate(upperBoundLayout()->layoutSize().height()+k_boundHeightMargin+(k_symbolHeight+1)/2, argumentLayout()->baseline()); + return std::max(upperBoundLayout()->layoutSize().height()+k_boundHeightMargin+(k_symbolHeight+1)/2, argumentLayout()->baseline()); } KDPoint SequenceLayoutNode::positionOfChild(LayoutNode * l) { @@ -193,10 +194,10 @@ KDPoint SequenceLayoutNode::positionOfChild(LayoutNode * l) { x = completeLowerBoundX() + equalSize.width() + variableSize.width(); y = baseline() + k_symbolHeight/2 + k_boundHeightMargin + subscriptBaseline() - lowerBoundLayout()->baseline(); } else if (l == upperBoundLayout()) { - x = maxCoordinate(maxCoordinate(0, (k_symbolWidth-upperBoundSize.width())/2), (lowerBoundSizeWithVariableEquals().width()-upperBoundSize.width())/2); + x = std::max(std::max(0, (k_symbolWidth-upperBoundSize.width())/2), (lowerBoundSizeWithVariableEquals().width()-upperBoundSize.width())/2); y = baseline() - (k_symbolHeight+1)/2- k_boundHeightMargin-upperBoundSize.height(); } else if (l == argumentLayout()) { - x = maxCoordinate(maxCoordinate(k_symbolWidth, lowerBoundSizeWithVariableEquals().width()), upperBoundSize.width())+k_argumentWidthMargin+ParenthesisLayoutNode::ParenthesisWidth(); + x = std::max(std::max(k_symbolWidth, lowerBoundSizeWithVariableEquals().width()), upperBoundSize.width())+k_argumentWidthMargin+ParenthesisLayoutNode::ParenthesisWidth(); y = baseline() - argumentLayout()->baseline(); } else { assert(false); @@ -267,12 +268,12 @@ void SequenceLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expressionCo KDCoordinate SequenceLayoutNode::completeLowerBoundX() { KDSize upperBoundSize = upperBoundLayout()->layoutSize(); - return maxCoordinate(maxCoordinate(0, (k_symbolWidth-lowerBoundSizeWithVariableEquals().width())/2), + return std::max(std::max(0, (k_symbolWidth-lowerBoundSizeWithVariableEquals().width())/2), (upperBoundSize.width()-lowerBoundSizeWithVariableEquals().width())/2); } KDCoordinate SequenceLayoutNode::subscriptBaseline() { - return maxCoordinate(maxCoordinate(variableLayout()->baseline(), lowerBoundLayout()->baseline()), k_font->stringSize(k_equal).height()/2); + return std::max(std::max(variableLayout()->baseline(), lowerBoundLayout()->baseline()), k_font->stringSize(k_equal).height()/2); } } diff --git a/poincare/src/solver.cpp b/poincare/src/solver.cpp index 33914717e..a5ea72bc3 100644 --- a/poincare/src/solver.cpp +++ b/poincare/src/solver.cpp @@ -230,11 +230,11 @@ T Solver::CumulativeDistributiveInverseForNDefinedFunction(T * probability, Valu do { delta = std::fabs(*probability-p); p += evaluation(k++, context, complexFormat, angleUnit, context1, context2, context3); - if (p >= k_maxProbability && std::fabs(*probability-1.0) <= delta) { + if (p >= k_maxProbability && std::fabs(*probability-(T)1.0) <= delta) { *probability = (T)1.0; return (T)(k-1); } - } while (std::fabs(*probability-p) <= delta && k < k_maxNumberOfOperations && p < 1.0); + } while (std::fabs(*probability-p) <= delta && k < k_maxNumberOfOperations && p < (T)1.0); p -= evaluation(--k, context, complexFormat, angleUnit, context1, context2, context3); if (k == k_maxNumberOfOperations) { *probability = (T)1.0; diff --git a/poincare/src/sum_layout.cpp b/poincare/src/sum_layout.cpp index 9d7cda716..64e27437c 100644 --- a/poincare/src/sum_layout.cpp +++ b/poincare/src/sum_layout.cpp @@ -1,11 +1,10 @@ #include #include #include +#include namespace Poincare { -static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } - const uint8_t symbolPixel[SumLayoutNode::k_symbolHeight][SumLayoutNode::k_symbolWidth] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, @@ -36,8 +35,8 @@ void SumLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expressionColor, // Render the Sum symbol. KDColor workingBuffer[k_symbolWidth*k_symbolHeight]; - KDRect symbolFrame(p.x() + maxCoordinate(maxCoordinate(0, (upperBoundSize.width()-k_symbolWidth)/2), (lowerBoundNEqualsSize.width()-k_symbolWidth)/2), - p.y() + maxCoordinate(upperBoundSize.height()+k_boundHeightMargin, argumentLayout()->baseline()-(k_symbolHeight+1)/2), + KDRect symbolFrame(p.x() + std::max(std::max(0, (upperBoundSize.width()-k_symbolWidth)/2), (lowerBoundNEqualsSize.width()-k_symbolWidth)/2), + p.y() + std::max(upperBoundSize.height()+k_boundHeightMargin, argumentLayout()->baseline()-(k_symbolHeight+1)/2), k_symbolWidth, k_symbolHeight); ctx->blendRectWithMask(symbolFrame, expressionColor, (const uint8_t *)symbolPixel, (KDColor *)workingBuffer); diff --git a/poincare/src/symbol_abstract.cpp b/poincare/src/symbol_abstract.cpp index a6708fdee..a7af63006 100644 --- a/poincare/src/symbol_abstract.cpp +++ b/poincare/src/symbol_abstract.cpp @@ -9,11 +9,10 @@ #include #include #include +#include namespace Poincare { -static inline int minInt(int x, int y) { return x < y ? x : y; } - size_t SymbolAbstractNode::size() const { return nodeSize() + strlen(name()) + 1; } @@ -35,13 +34,13 @@ Expression SymbolAbstractNode::setSign(ExpressionNode::Sign s, ReductionContext return e.setSign(s, reductionContext); } -int SymbolAbstractNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const { +int SymbolAbstractNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const { assert(type() == e->type()); return strcmp(name(), static_cast(e)->name()); } int SymbolAbstractNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return minInt(strlcpy(buffer, name(), bufferSize), bufferSize - 1); + return std::min(strlcpy(buffer, name(), bufferSize), bufferSize - 1); } template diff --git a/poincare/src/tree_handle.cpp b/poincare/src/tree_handle.cpp index 3e87d6f7a..97e7fbfc1 100644 --- a/poincare/src/tree_handle.cpp +++ b/poincare/src/tree_handle.cpp @@ -212,19 +212,22 @@ TreeHandle TreeHandle::Builder() { } template -T TreeHandle::NAryBuilder(TreeHandle * children, size_t numberOfChildren) { +T TreeHandle::NAryBuilder(const Tuple & children) { TreeHandle h = Builder(); - for (size_t i = 0; i < numberOfChildren; i++) { - h.addChildAtIndexInPlace(children[i], i, i); + size_t i = 0; + for (TreeHandle child : children) { + h.addChildAtIndexInPlace(child, i, i); + i++; } return static_cast(h); } template -T TreeHandle::FixedArityBuilder(TreeHandle * children, size_t numberOfChildren) { +T TreeHandle::FixedArityBuilder(const Tuple & children) { TreeHandle h = Builder(); - for (size_t i = 0; i < numberOfChildren; i++) { - h.replaceChildAtIndexInPlace(i, children[i]); + size_t i = 0; + for (TreeHandle child : children) { + h.replaceChildAtIndexInPlace(i++, child); } return static_cast(h); } @@ -277,96 +280,96 @@ void TreeHandle::release(uint16_t identifier) { node->release(node->numberOfChildren()); } -template AbsoluteValue TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template AbsoluteValueLayout TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Addition TreeHandle::NAryBuilder(TreeHandle*, size_t); -template ArcCosine TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template ArcSine TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template ArcTangent TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template BinomCDF TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template BinomialCoefficient TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template BinomialCoefficientLayout TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template BinomPDF TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Ceiling TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template CeilingLayout TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template CommonLogarithm TreeHandle::FixedArityBuilder >(TreeHandle*, size_t); -template ComplexArgument TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template ComplexCartesian TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template CondensedSumLayout TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template ConfidenceInterval TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Conjugate TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template ConjugateLayout TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Cosine TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Derivative TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Determinant TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Division TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template DivisionQuotient TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template DivisionRemainder TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template EmptyExpression TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Equal TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Factor TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Factorial TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Floor TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template FloorLayout TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template FracPart TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template FractionLayout TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Ghost TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template GreatCommonDivisor TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template HorizontalLayout TreeHandle::NAryBuilder(TreeHandle*, size_t); -template HyperbolicArcCosine TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template HyperbolicArcSine TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template HyperbolicArcTangent TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template HyperbolicCosine TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template HyperbolicSine TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template HyperbolicTangent TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template ImaginaryPart TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Integral TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template IntegralLayout TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template InvBinom TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template InvNorm TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template LeastCommonMultiple TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template LeftParenthesisLayout TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template LeftSquareBracketLayout TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Logarithm TreeHandle::FixedArityBuilder >(TreeHandle*, size_t); -template Matrix TreeHandle::NAryBuilder(TreeHandle*, size_t); -template MatrixComplex TreeHandle::NAryBuilder, MatrixComplexNode >(TreeHandle*, size_t); -template MatrixComplex TreeHandle::NAryBuilder, MatrixComplexNode >(TreeHandle*, size_t); -template MatrixDimension TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template MatrixIdentity TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template MatrixInverse TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template MatrixTrace TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template MatrixTranspose TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Multiplication TreeHandle::NAryBuilder(TreeHandle*, size_t); -template NaperianLogarithm TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template NormCDF TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template NormCDF2 TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template NormPDF TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template NthRoot TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Opposite TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Parenthesis TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template PermuteCoefficient TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Power TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template PredictionInterval TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Product TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template ProductLayout TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Randint TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Random TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template RealPart TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template RightParenthesisLayout TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template RightSquareBracketLayout TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Round TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template SignFunction TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template SimplePredictionInterval TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Sine TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template SquareRoot TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Store TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Subtraction TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Sum TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template SumLayout TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Tangent TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Undefined TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template UnitConvert TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template Unreal TreeHandle::FixedArityBuilder(TreeHandle*, size_t); -template MatrixLayout TreeHandle::NAryBuilder(TreeHandle*, size_t); +template AbsoluteValue TreeHandle::FixedArityBuilder(const Tuple &); +template AbsoluteValueLayout TreeHandle::FixedArityBuilder(const Tuple &); +template Addition TreeHandle::NAryBuilder(const Tuple &); +template ArcCosine TreeHandle::FixedArityBuilder(const Tuple &); +template ArcSine TreeHandle::FixedArityBuilder(const Tuple &); +template ArcTangent TreeHandle::FixedArityBuilder(const Tuple &); +template BinomCDF TreeHandle::FixedArityBuilder(const Tuple &); +template BinomialCoefficient TreeHandle::FixedArityBuilder(const Tuple &); +template BinomialCoefficientLayout TreeHandle::FixedArityBuilder(const Tuple &); +template BinomPDF TreeHandle::FixedArityBuilder(const Tuple &); +template Ceiling TreeHandle::FixedArityBuilder(const Tuple &); +template CeilingLayout TreeHandle::FixedArityBuilder(const Tuple &); +template CommonLogarithm TreeHandle::FixedArityBuilder >(const Tuple &); +template ComplexArgument TreeHandle::FixedArityBuilder(const Tuple &); +template ComplexCartesian TreeHandle::FixedArityBuilder(const Tuple &); +template CondensedSumLayout TreeHandle::FixedArityBuilder(const Tuple &); +template ConfidenceInterval TreeHandle::FixedArityBuilder(const Tuple &); +template Conjugate TreeHandle::FixedArityBuilder(const Tuple &); +template ConjugateLayout TreeHandle::FixedArityBuilder(const Tuple &); +template Cosine TreeHandle::FixedArityBuilder(const Tuple &); +template Derivative TreeHandle::FixedArityBuilder(const Tuple &); +template Determinant TreeHandle::FixedArityBuilder(const Tuple &); +template Division TreeHandle::FixedArityBuilder(const Tuple &); +template DivisionQuotient TreeHandle::FixedArityBuilder(const Tuple &); +template DivisionRemainder TreeHandle::FixedArityBuilder(const Tuple &); +template EmptyExpression TreeHandle::FixedArityBuilder(const Tuple &); +template Equal TreeHandle::FixedArityBuilder(const Tuple &); +template Factor TreeHandle::FixedArityBuilder(const Tuple &); +template Factorial TreeHandle::FixedArityBuilder(const Tuple &); +template Floor TreeHandle::FixedArityBuilder(const Tuple &); +template FloorLayout TreeHandle::FixedArityBuilder(const Tuple &); +template FracPart TreeHandle::FixedArityBuilder(const Tuple &); +template FractionLayout TreeHandle::FixedArityBuilder(const Tuple &); +template Ghost TreeHandle::FixedArityBuilder(const Tuple &); +template GreatCommonDivisor TreeHandle::FixedArityBuilder(const Tuple &); +template HorizontalLayout TreeHandle::NAryBuilder(const Tuple &); +template HyperbolicArcCosine TreeHandle::FixedArityBuilder(const Tuple &); +template HyperbolicArcSine TreeHandle::FixedArityBuilder(const Tuple &); +template HyperbolicArcTangent TreeHandle::FixedArityBuilder(const Tuple &); +template HyperbolicCosine TreeHandle::FixedArityBuilder(const Tuple &); +template HyperbolicSine TreeHandle::FixedArityBuilder(const Tuple &); +template HyperbolicTangent TreeHandle::FixedArityBuilder(const Tuple &); +template ImaginaryPart TreeHandle::FixedArityBuilder(const Tuple &); +template Integral TreeHandle::FixedArityBuilder(const Tuple &); +template IntegralLayout TreeHandle::FixedArityBuilder(const Tuple &); +template InvBinom TreeHandle::FixedArityBuilder(const Tuple &); +template InvNorm TreeHandle::FixedArityBuilder(const Tuple &); +template LeastCommonMultiple TreeHandle::FixedArityBuilder(const Tuple &); +template LeftParenthesisLayout TreeHandle::FixedArityBuilder(const Tuple &); +template LeftSquareBracketLayout TreeHandle::FixedArityBuilder(const Tuple &); +template Logarithm TreeHandle::FixedArityBuilder >(const Tuple &); +template Matrix TreeHandle::NAryBuilder(const Tuple &); +template MatrixComplex TreeHandle::NAryBuilder, MatrixComplexNode >(const Tuple &); +template MatrixComplex TreeHandle::NAryBuilder, MatrixComplexNode >(const Tuple &); +template MatrixDimension TreeHandle::FixedArityBuilder(const Tuple &); +template MatrixIdentity TreeHandle::FixedArityBuilder(const Tuple &); +template MatrixInverse TreeHandle::FixedArityBuilder(const Tuple &); +template MatrixTrace TreeHandle::FixedArityBuilder(const Tuple &); +template MatrixTranspose TreeHandle::FixedArityBuilder(const Tuple &); +template Multiplication TreeHandle::NAryBuilder(const Tuple &); +template NaperianLogarithm TreeHandle::FixedArityBuilder(const Tuple &); +template NormCDF TreeHandle::FixedArityBuilder(const Tuple &); +template NormCDF2 TreeHandle::FixedArityBuilder(const Tuple &); +template NormPDF TreeHandle::FixedArityBuilder(const Tuple &); +template NthRoot TreeHandle::FixedArityBuilder(const Tuple &); +template Opposite TreeHandle::FixedArityBuilder(const Tuple &); +template Parenthesis TreeHandle::FixedArityBuilder(const Tuple &); +template PermuteCoefficient TreeHandle::FixedArityBuilder(const Tuple &); +template Power TreeHandle::FixedArityBuilder(const Tuple &); +template PredictionInterval TreeHandle::FixedArityBuilder(const Tuple &); +template Product TreeHandle::FixedArityBuilder(const Tuple &); +template ProductLayout TreeHandle::FixedArityBuilder(const Tuple &); +template Randint TreeHandle::FixedArityBuilder(const Tuple &); +template Random TreeHandle::FixedArityBuilder(const Tuple &); +template RealPart TreeHandle::FixedArityBuilder(const Tuple &); +template RightParenthesisLayout TreeHandle::FixedArityBuilder(const Tuple &); +template RightSquareBracketLayout TreeHandle::FixedArityBuilder(const Tuple &); +template Round TreeHandle::FixedArityBuilder(const Tuple &); +template SignFunction TreeHandle::FixedArityBuilder(const Tuple &); +template SimplePredictionInterval TreeHandle::FixedArityBuilder(const Tuple &); +template Sine TreeHandle::FixedArityBuilder(const Tuple &); +template SquareRoot TreeHandle::FixedArityBuilder(const Tuple &); +template Store TreeHandle::FixedArityBuilder(const Tuple &); +template Subtraction TreeHandle::FixedArityBuilder(const Tuple &); +template Sum TreeHandle::FixedArityBuilder(const Tuple &); +template SumLayout TreeHandle::FixedArityBuilder(const Tuple &); +template Tangent TreeHandle::FixedArityBuilder(const Tuple &); +template Undefined TreeHandle::FixedArityBuilder(const Tuple &); +template UnitConvert TreeHandle::FixedArityBuilder(const Tuple &); +template Unreal TreeHandle::FixedArityBuilder(const Tuple &); +template MatrixLayout TreeHandle::NAryBuilder(const Tuple &); } diff --git a/poincare/src/trigonometry.cpp b/poincare/src/trigonometry.cpp index 168f7e49d..7ece0a2cc 100644 --- a/poincare/src/trigonometry.cpp +++ b/poincare/src/trigonometry.cpp @@ -399,7 +399,7 @@ Expression Trigonometry::shallowReduceInverseFunction(Expression & e, Expressio template std::complex Trigonometry::ConvertToRadian(const std::complex c, Preferences::AngleUnit angleUnit) { if (angleUnit != Preferences::AngleUnit::Radian) { - return c * std::complex(M_PI/Trigonometry::PiInAngleUnit(angleUnit)); + return c * std::complex((T)M_PI/(T)Trigonometry::PiInAngleUnit(angleUnit)); } return c; } @@ -407,7 +407,7 @@ std::complex Trigonometry::ConvertToRadian(const std::complex c, Preferenc template std::complex Trigonometry::ConvertRadianToAngleUnit(const std::complex c, Preferences::AngleUnit angleUnit) { if (angleUnit != Preferences::AngleUnit::Radian) { - return c * std::complex(Trigonometry::PiInAngleUnit(angleUnit)/M_PI); + return c * std::complex((T)Trigonometry::PiInAngleUnit(angleUnit)/(T)M_PI); } return c; } diff --git a/poincare/src/undefined.cpp b/poincare/src/undefined.cpp index 0a7a8c1a6..dfc7b4d15 100644 --- a/poincare/src/undefined.cpp +++ b/poincare/src/undefined.cpp @@ -1,6 +1,7 @@ #include #include #include +#include extern "C" { #include @@ -9,8 +10,6 @@ extern "C" { namespace Poincare { -static inline int minInt(int x, int y) { return x < y ? x : y; } - int UndefinedNode::polynomialDegree(Context * context, const char * symbolName) const { return -1; } @@ -25,7 +24,7 @@ Layout UndefinedNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, } int UndefinedNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return minInt(strlcpy(buffer, Undefined::Name(), bufferSize), bufferSize - 1); + return std::min(strlcpy(buffer, Undefined::Name(), bufferSize), bufferSize - 1); } template Evaluation UndefinedNode::templatedApproximate() const { diff --git a/poincare/src/unit.cpp b/poincare/src/unit.cpp index eb12cf306..cc30b9daf 100644 --- a/poincare/src/unit.cpp +++ b/poincare/src/unit.cpp @@ -10,15 +10,15 @@ #include #include #include +#include namespace Poincare { static inline int absInt(int x) { return x >= 0 ? x : -x; } -static inline int minInt(int x, int y) { return x < y ? x : y; } int UnitNode::Prefix::serialize(char * buffer, int bufferSize) const { assert(bufferSize >= 0); - return minInt(strlcpy(buffer, m_symbol, bufferSize), bufferSize - 1); + return std::min(strlcpy(buffer, m_symbol, bufferSize), bufferSize - 1); } bool UnitNode::Representative::canParse(const char * symbol, size_t length, @@ -51,7 +51,7 @@ int UnitNode::Representative::serialize(char * buffer, int bufferSize, const Pre bufferSize -= length; } assert(bufferSize >= 0); - length += minInt(strlcpy(buffer, m_rootSymbol, bufferSize), bufferSize - 1); + length += std::min(strlcpy(buffer, m_rootSymbol, bufferSize), bufferSize - 1); return length; } @@ -103,9 +103,9 @@ Expression UnitNode::getUnit() const { return Unit(this).getUnit(); } -int UnitNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted) const { +int UnitNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const { if (!ascending) { - return e->simplificationOrderSameType(this, true, canBeInterrupted); + return e->simplificationOrderSameType(this, true, canBeInterrupted, ignoreParentheses); } assert(type() == e->type()); const UnitNode * eNode = static_cast(e); @@ -134,7 +134,7 @@ Layout UnitNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int int UnitNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { assert(bufferSize >= 0); - int underscoreLength = minInt(strlcpy(buffer, "_", bufferSize), bufferSize - 1); + int underscoreLength = std::min(strlcpy(buffer, "_", bufferSize), bufferSize - 1); buffer += underscoreLength; bufferSize -= underscoreLength; return underscoreLength + m_representative->serialize(buffer, bufferSize, m_prefix); @@ -303,7 +303,7 @@ void Unit::chooseBestMultipleForValue(double & value, const int exponent, Expres double val = value * std::pow(Division::Builder(clone(), Unit::Builder(dim, rep, &EmptyPrefix)).deepReduce(reductionContext).approximateToScalar(reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit()), exponent); // Get the best prefix and update val accordingly const Prefix * pre = rep->bestPrefixForValue(val, exponent); - if (std::fabs(std::log10(std::fabs(val))) < std::fabs(std::log10(std::fabs(bestVal)))) { + if (std::fabs(std::log10(std::fabs(bestVal))) - std::fabs(std::log10(std::fabs(val))) > Epsilon()) { /* At this point, val is closer to one than bestVal is.*/ bestRep = rep; bestPre = pre; diff --git a/poincare/src/unreal.cpp b/poincare/src/unreal.cpp index ca2a9ddd8..10e0eb6fd 100644 --- a/poincare/src/unreal.cpp +++ b/poincare/src/unreal.cpp @@ -1,5 +1,6 @@ #include #include +#include extern "C" { #include @@ -8,14 +9,12 @@ extern "C" { namespace Poincare { -static inline int minInt(int x, int y) { return x < y ? x : y; } - Layout UnrealNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { return LayoutHelper::String(Unreal::Name(), Unreal::NameSize()-1); } int UnrealNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return minInt(strlcpy(buffer, Unreal::Name(), bufferSize), bufferSize - 1); + return std::min(strlcpy(buffer, Unreal::Name(), bufferSize), bufferSize - 1); } } diff --git a/poincare/src/vertical_offset_layout.cpp b/poincare/src/vertical_offset_layout.cpp index df163f402..40d6571ff 100644 --- a/poincare/src/vertical_offset_layout.cpp +++ b/poincare/src/vertical_offset_layout.cpp @@ -5,11 +5,10 @@ #include #include #include +#include namespace Poincare { -static inline int minInt(int x, int y) { return x < y ? x : y; } - void VerticalOffsetLayoutNode::moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout, bool forSelection) { if (cursor->layoutNode() == indiceLayout() && cursor->position() == LayoutCursor::Position::Left) @@ -165,7 +164,7 @@ int VerticalOffsetLayoutNode::serialize(char * buffer, int bufferSize, Preferenc if (numberOfChar >= bufferSize-1) { return bufferSize-1; } numberOfChar += SerializationHelper::CodePoint(buffer+numberOfChar, bufferSize-numberOfChar, '}'); - return minInt(numberOfChar, bufferSize-1); + return std::min(numberOfChar, bufferSize-1); } assert(m_position == Position::Superscript); @@ -177,7 +176,7 @@ int VerticalOffsetLayoutNode::serialize(char * buffer, int bufferSize, Preferenc numberOfChar += const_cast(this)->indiceLayout()->serialize(buffer+numberOfChar, bufferSize-numberOfChar, floatDisplayMode, numberOfSignificantDigits); if (numberOfChar >= bufferSize-1) { return bufferSize-1; } numberOfChar += SerializationHelper::CodePoint(buffer+numberOfChar, bufferSize-numberOfChar, UCodePointRightSystemParenthesis); - return minInt(numberOfChar, bufferSize-1); + return std::min(numberOfChar, bufferSize-1); } KDSize VerticalOffsetLayoutNode::computeSize() { diff --git a/poincare/test/approximation.cpp b/poincare/test/approximation.cpp index 723027d6e..d985b1c8e 100644 --- a/poincare/test/approximation.cpp +++ b/poincare/test/approximation.cpp @@ -580,10 +580,10 @@ QUIZ_CASE(poincare_approximation_trigonometry_functions) { // Key values assert_expression_approximates_to("asin(0)", "0", Degree); assert_expression_approximates_to("asin(0)", "0", Gradian); - assert_expression_approximates_to("asin(-1)", "-90", Degree); - assert_expression_approximates_to("asin(-1)", "-100", Gradian, Cartesian, 3); + assert_expression_approximates_to("asin(-1)", "-90", Degree, Cartesian, 6); + assert_expression_approximates_to("asin(-1)", "-100", Gradian, Cartesian, 6); assert_expression_approximates_to("asin(1)", "90", Degree); - assert_expression_approximates_to("asin(1)", "100", Gradian, Cartesian, 3); + assert_expression_approximates_to("asin(1)", "100", Gradian, Cartesian); /* atan: R -> R (odd) * [-𝐢,𝐢] -> R×𝐢 (odd) @@ -779,11 +779,11 @@ QUIZ_CASE(poincare_approximation_trigonometry_functions) { assert_expression_approximates_to("atanh(𝐢-4)", "-0.238878+1.50862×𝐢", Degree, Cartesian, 6); // Check that the complex part is not neglected - assert_expression_approximates_to("atanh(0.99999999999+1.0ᴇ-26×𝐢)", "13.01+5ᴇ-16×𝐢", Radian, Cartesian, 4); - assert_expression_approximates_to("atanh(0.99999999999+1.0ᴇ-60×𝐢)", "13.01+5ᴇ-50×𝐢", Radian, Cartesian, 4); - assert_expression_approximates_to("atanh(0.99999999999+1.0ᴇ-150×𝐢)", "13.01+5ᴇ-140×𝐢", Radian, Cartesian, 4); - assert_expression_approximates_to("atanh(0.99999999999+1.0ᴇ-250×𝐢)", "13.01+5ᴇ-240×𝐢", Radian, Cartesian, 4); - assert_expression_approximates_to("atanh(0.99999999999+1.0ᴇ-300×𝐢)", "13.01+5ᴇ-290×𝐢", Radian, Cartesian, 4); + assert_expression_approximates_to("atanh(0.99999999999+1.0ᴇ-26×𝐢)", "13+5ᴇ-16×𝐢", Radian, Cartesian, 3); + assert_expression_approximates_to("atanh(0.99999999999+1.0ᴇ-60×𝐢)", "13+5ᴇ-50×𝐢", Radian, Cartesian, 3); + assert_expression_approximates_to("atanh(0.99999999999+1.0ᴇ-150×𝐢)", "13+5ᴇ-140×𝐢", Radian, Cartesian, 3); + assert_expression_approximates_to("atanh(0.99999999999+1.0ᴇ-250×𝐢)", "13+5ᴇ-240×𝐢", Radian, Cartesian, 3); + assert_expression_approximates_to("atanh(0.99999999999+1.0ᴇ-300×𝐢)", "13+5ᴇ-290×𝐢", Radian, Cartesian, 3); // WARNING: evaluate on branch cut can be multivalued assert_expression_approximates_to("acos(2)", "1.3169578969248×𝐢", Radian); diff --git a/poincare/test/expression_order.cpp b/poincare/test/expression_order.cpp index adf4ed1be..33a9b2512 100644 --- a/poincare/test/expression_order.cpp +++ b/poincare/test/expression_order.cpp @@ -98,11 +98,16 @@ QUIZ_CASE(poincare_expression_order_addition_multiplication) { } { // 1 + 2 + 0 -> 2 + 1 + 0 - constexpr int numberOfChildren = 3; - 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); + Expression e1 = Addition::Builder({ + Rational::Builder(1), + Rational::Builder(2), + Rational::Builder(0) + }); + Expression e2 = Addition::Builder({ + Rational::Builder(2), + Rational::Builder(1), + Rational::Builder(0) + }); assert_multiplication_or_addition_is_ordered_as(e1, e2); } { @@ -110,11 +115,8 @@ QUIZ_CASE(poincare_expression_order_addition_multiplication) { Expression pi = Constant::Builder(UCodePointGreekSmallLetterPi); Expression i = Constant::Builder(UCodePointMathematicalBoldSmallI); Expression e = Constant::Builder(UCodePointScriptSmallE); - constexpr int numberOfChildren = 3; - Expression children[numberOfChildren] = {pi.clone(), i.clone(), e.clone()}; - Expression childrenSorted[numberOfChildren] = {e, pi, i}; - Expression e1 = Addition::Builder(children, numberOfChildren); - Expression e2 = Addition::Builder(childrenSorted, numberOfChildren); + Expression e1 = Addition::Builder({pi.clone(), i.clone(), e.clone()}); + Expression e2 = Addition::Builder({e, pi, i}); assert_multiplication_or_addition_is_ordered_as(e1, e2); } { @@ -124,22 +126,19 @@ QUIZ_CASE(poincare_expression_order_addition_multiplication) { assert_multiplication_or_addition_is_ordered_as(e1, e2); } { - constexpr int numberOfChildren = 4; - Expression children[numberOfChildren] = { + // c + b^2 + a^2 + a -> a^2 + a + b^2 + c + Expression e1 = Addition::Builder({ 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] = { + }); + Expression e2 = Addition::Builder({ Power::Builder(Symbol::Builder('a'), Rational::Builder(2)), Symbol::Builder('a'), Power::Builder(Symbol::Builder('b'), Rational::Builder(2)), Symbol::Builder('c') - }; - // c + b^2 + a^2 + a -> a^2 + a + b^2 + c - Expression e1 = Addition::Builder(children, numberOfChildren); - Expression e2 = Addition::Builder(childrenSorted, numberOfChildren); + }); assert_multiplication_or_addition_is_ordered_as(e1, e2); } { @@ -194,21 +193,18 @@ QUIZ_CASE(poincare_expression_order_addition_multiplication) { Expression childMatrix2 = Matrix::Builder(); static_cast(childMatrix2).addChildAtIndexInPlace(Rational::Builder(0), 0, 0); - constexpr int numberOfChildren = 4; - Expression children[numberOfChildren] = { + Expression e1 = Multiplication::Builder({ child2.clone(), childMatrix1.clone(), childMatrix2.clone(), child1.clone() - }; - Expression childrenSorted[numberOfChildren] = { + }); + Expression e2 = Multiplication::Builder({ child1.clone(), child2.clone(), childMatrix1.clone(), childMatrix2.clone() - }; - Expression e1 = Multiplication::Builder(children, numberOfChildren); - Expression e2 = Multiplication::Builder(childrenSorted, numberOfChildren); + }); assert_multiplication_or_addition_is_ordered_as(e1, e2); } diff --git a/poincare/test/layout_to_expression.cpp b/poincare/test/layout_to_expression.cpp index fc6a819cc..6e99ebc69 100644 --- a/poincare/test/layout_to_expression.cpp +++ b/poincare/test/layout_to_expression.cpp @@ -43,19 +43,18 @@ QUIZ_CASE(poincare_layout_to_expression_unparsable) { * ∑ (5) * n=1 */ - constexpr int childrenCount = 5; - Layout children[childrenCount] = { - CodePointLayout::Builder('2'), - RightParenthesisLayout::Builder(), - CodePointLayout::Builder('+'), - LeftParenthesisLayout::Builder(), - CodePointLayout::Builder('1')}; - Layout l = SumLayout::Builder( - CodePointLayout::Builder('5'), - CodePointLayout::Builder('n'), - CodePointLayout::Builder('1'), - HorizontalLayout::Builder(children, childrenCount)); + CodePointLayout::Builder('5'), + CodePointLayout::Builder('n'), + CodePointLayout::Builder('1'), + HorizontalLayout::Builder({ + CodePointLayout::Builder('2'), + RightParenthesisLayout::Builder(), + CodePointLayout::Builder('+'), + LeftParenthesisLayout::Builder(), + CodePointLayout::Builder('1') + }) + ); assert_layout_is_not_parsed(l); } @@ -64,34 +63,30 @@ QUIZ_CASE(poincare_layout_to_expression_unparsable) { * π (5) * n=1+binomial(3 */ - - constexpr int children1Count = 12; - Layout children1[children1Count] = { - CodePointLayout::Builder('1'), - CodePointLayout::Builder('+'), - CodePointLayout::Builder('b'), - CodePointLayout::Builder('i'), - CodePointLayout::Builder('n'), - CodePointLayout::Builder('o'), - CodePointLayout::Builder('m'), - CodePointLayout::Builder('i'), - CodePointLayout::Builder('a'), - CodePointLayout::Builder('l'), - LeftParenthesisLayout::Builder(), - CodePointLayout::Builder('3')}; - - constexpr int children2Count = 4; - Layout children2[children2Count] = { - CodePointLayout::Builder('2'), - RightParenthesisLayout::Builder(), - CodePointLayout::Builder(','), - CodePointLayout::Builder('1')}; - Layout l = SumLayout::Builder( - CodePointLayout::Builder('5'), + CodePointLayout::Builder('5'), + CodePointLayout::Builder('n'), + HorizontalLayout::Builder({ + CodePointLayout::Builder('1'), + CodePointLayout::Builder('+'), + CodePointLayout::Builder('b'), + CodePointLayout::Builder('i'), CodePointLayout::Builder('n'), - HorizontalLayout::Builder(children1, children1Count), - HorizontalLayout::Builder(children2, children2Count)); + CodePointLayout::Builder('o'), + CodePointLayout::Builder('m'), + CodePointLayout::Builder('i'), + CodePointLayout::Builder('a'), + CodePointLayout::Builder('l'), + LeftParenthesisLayout::Builder(), + CodePointLayout::Builder('3') + }), + HorizontalLayout::Builder({ + CodePointLayout::Builder('2'), + RightParenthesisLayout::Builder(), + CodePointLayout::Builder(','), + CodePointLayout::Builder('1') + }) + ); assert_layout_is_not_parsed(l); } @@ -100,19 +95,18 @@ QUIZ_CASE(poincare_layout_to_expression_unparsable) { * π (5) * n=1 */ - constexpr int childrenCount = 5; - Layout children[childrenCount] = { - CodePointLayout::Builder('2'), - RightParenthesisLayout::Builder(), - CodePointLayout::Builder('+'), - LeftParenthesisLayout::Builder(), - CodePointLayout::Builder('1')}; - Layout l = ProductLayout::Builder( - CodePointLayout::Builder('5'), - CodePointLayout::Builder('n'), - CodePointLayout::Builder('1'), - HorizontalLayout::Builder(children, childrenCount)); + CodePointLayout::Builder('5'), + CodePointLayout::Builder('n'), + CodePointLayout::Builder('1'), + HorizontalLayout::Builder({ + CodePointLayout::Builder('2'), + RightParenthesisLayout::Builder(), + CodePointLayout::Builder('+'), + LeftParenthesisLayout::Builder(), + CodePointLayout::Builder('1') + }) + ); assert_layout_is_not_parsed(l); } @@ -121,34 +115,30 @@ QUIZ_CASE(poincare_layout_to_expression_unparsable) { * π (5) * n=1+binomial(3 */ - - constexpr int children1Count = 12; - Layout children1[children1Count] = { - CodePointLayout::Builder('1'), - CodePointLayout::Builder('+'), - CodePointLayout::Builder('b'), - CodePointLayout::Builder('i'), - CodePointLayout::Builder('n'), - CodePointLayout::Builder('o'), - CodePointLayout::Builder('m'), - CodePointLayout::Builder('i'), - CodePointLayout::Builder('a'), - CodePointLayout::Builder('l'), - LeftParenthesisLayout::Builder(), - CodePointLayout::Builder('3')}; - - constexpr int children2Count = 4; - Layout children2[children2Count] = { - CodePointLayout::Builder('2'), - RightParenthesisLayout::Builder(), - CodePointLayout::Builder(','), - CodePointLayout::Builder('1')}; - Layout l = ProductLayout::Builder( - CodePointLayout::Builder('5'), + CodePointLayout::Builder('5'), + CodePointLayout::Builder('n'), + HorizontalLayout::Builder({ + CodePointLayout::Builder('1'), + CodePointLayout::Builder('+'), + CodePointLayout::Builder('b'), + CodePointLayout::Builder('i'), CodePointLayout::Builder('n'), - HorizontalLayout::Builder(children1, children1Count), - HorizontalLayout::Builder(children2, children2Count)); + CodePointLayout::Builder('o'), + CodePointLayout::Builder('m'), + CodePointLayout::Builder('i'), + CodePointLayout::Builder('a'), + CodePointLayout::Builder('l'), + LeftParenthesisLayout::Builder(), + CodePointLayout::Builder('3') + }), + HorizontalLayout::Builder({ + CodePointLayout::Builder('2'), + RightParenthesisLayout::Builder(), + CodePointLayout::Builder(','), + CodePointLayout::Builder('1') + }) + ); assert_layout_is_not_parsed(l); } @@ -157,19 +147,18 @@ QUIZ_CASE(poincare_layout_to_expression_unparsable) { * ∫ (5)dx * 1 */ - constexpr int childrenCount = 5; - Layout children[childrenCount] = { - CodePointLayout::Builder('2'), - RightParenthesisLayout::Builder(), - CodePointLayout::Builder('+'), - LeftParenthesisLayout::Builder(), - CodePointLayout::Builder('1')}; - Layout l = IntegralLayout::Builder( - CodePointLayout::Builder('5'), - CodePointLayout::Builder('x'), - CodePointLayout::Builder('1'), - HorizontalLayout::Builder(children, childrenCount)); + CodePointLayout::Builder('5'), + CodePointLayout::Builder('x'), + CodePointLayout::Builder('1'), + HorizontalLayout::Builder({ + CodePointLayout::Builder('2'), + RightParenthesisLayout::Builder(), + CodePointLayout::Builder('+'), + LeftParenthesisLayout::Builder(), + CodePointLayout::Builder('1') + }) + ); assert_layout_is_not_parsed(l); } @@ -178,48 +167,42 @@ QUIZ_CASE(poincare_layout_to_expression_unparsable) { * ∫ (5)dx * 1+binomial(3 */ - - constexpr int children1Count = 12; - Layout children1[children1Count] = { - CodePointLayout::Builder('1'), - CodePointLayout::Builder('+'), - CodePointLayout::Builder('b'), - CodePointLayout::Builder('i'), - CodePointLayout::Builder('n'), - CodePointLayout::Builder('o'), - CodePointLayout::Builder('m'), - CodePointLayout::Builder('i'), - CodePointLayout::Builder('a'), - CodePointLayout::Builder('l'), - LeftParenthesisLayout::Builder(), - CodePointLayout::Builder('3')}; - - constexpr int children2Count = 4; - Layout children2[children2Count] = { - CodePointLayout::Builder('2'), - RightParenthesisLayout::Builder(), - CodePointLayout::Builder(','), - CodePointLayout::Builder('1')}; - Layout l = IntegralLayout::Builder( - CodePointLayout::Builder('5'), - CodePointLayout::Builder('x'), - HorizontalLayout::Builder(children1, children1Count), - HorizontalLayout::Builder(children2, children2Count)); + CodePointLayout::Builder('5'), + CodePointLayout::Builder('x'), + HorizontalLayout::Builder({ + CodePointLayout::Builder('1'), + CodePointLayout::Builder('+'), + CodePointLayout::Builder('b'), + CodePointLayout::Builder('i'), + CodePointLayout::Builder('n'), + CodePointLayout::Builder('o'), + CodePointLayout::Builder('m'), + CodePointLayout::Builder('i'), + CodePointLayout::Builder('a'), + CodePointLayout::Builder('l'), + LeftParenthesisLayout::Builder(), + CodePointLayout::Builder('3') + }), + HorizontalLayout::Builder({ + CodePointLayout::Builder('2'), + RightParenthesisLayout::Builder(), + CodePointLayout::Builder(','), + CodePointLayout::Builder('1') + }) + ); assert_layout_is_not_parsed(l); } { // |3)+(1| - constexpr int childrenCount = 5; - Layout children[childrenCount] = { + Layout l = AbsoluteValueLayout::Builder(HorizontalLayout::Builder({ CodePointLayout::Builder('3'), RightParenthesisLayout::Builder(), CodePointLayout::Builder('+'), LeftParenthesisLayout::Builder(), - CodePointLayout::Builder('1')}; - - Layout l = AbsoluteValueLayout::Builder(HorizontalLayout::Builder(children, childrenCount)); + CodePointLayout::Builder('1') + })); assert_layout_is_not_parsed(l); } @@ -229,31 +212,28 @@ QUIZ_CASE(poincare_layout_to_expression_unparsable) { * | 1),1 | * \ / */ - constexpr int children1Count = 12; - Layout children1[children1Count] = { - CodePointLayout::Builder('1'), - CodePointLayout::Builder('+'), - CodePointLayout::Builder('b'), - CodePointLayout::Builder('i'), - CodePointLayout::Builder('n'), - CodePointLayout::Builder('o'), - CodePointLayout::Builder('m'), - CodePointLayout::Builder('i'), - CodePointLayout::Builder('a'), - CodePointLayout::Builder('l'), - LeftParenthesisLayout::Builder(), - CodePointLayout::Builder('3')}; - - constexpr int children2Count = 4; - Layout children2[children2Count] = { - CodePointLayout::Builder('1'), - RightParenthesisLayout::Builder(), - CodePointLayout::Builder(','), - CodePointLayout::Builder('1')}; - Layout l = BinomialCoefficientLayout::Builder( - HorizontalLayout::Builder(children1, children1Count), - HorizontalLayout::Builder(children2, children2Count)); + HorizontalLayout::Builder({ + CodePointLayout::Builder('1'), + CodePointLayout::Builder('+'), + CodePointLayout::Builder('b'), + CodePointLayout::Builder('i'), + CodePointLayout::Builder('n'), + CodePointLayout::Builder('o'), + CodePointLayout::Builder('m'), + CodePointLayout::Builder('i'), + CodePointLayout::Builder('a'), + CodePointLayout::Builder('l'), + LeftParenthesisLayout::Builder(), + CodePointLayout::Builder('3') + }), + HorizontalLayout::Builder({ + CodePointLayout::Builder('1'), + RightParenthesisLayout::Builder(), + CodePointLayout::Builder(','), + CodePointLayout::Builder('1') + }) + ); assert_layout_is_not_parsed(l); } } diff --git a/poincare/test/parsing.cpp b/poincare/test/parsing.cpp index 328d50661..8d01d0f2b 100644 --- a/poincare/test/parsing.cpp +++ b/poincare/test/parsing.cpp @@ -169,13 +169,11 @@ QUIZ_CASE(poincare_parsing_parse) { assert_parsed_expression_is("1+2", Addition::Builder(BasedInteger::Builder(1),BasedInteger::Builder(2))); assert_parsed_expression_is("(1)+2", Addition::Builder(Parenthesis::Builder(BasedInteger::Builder(1)),BasedInteger::Builder(2))); assert_parsed_expression_is("(1+2)", Parenthesis::Builder(Addition::Builder(BasedInteger::Builder(1),BasedInteger::Builder(2)))); - Expression nAryChildren[] = {BasedInteger::Builder(1),BasedInteger::Builder(2),BasedInteger::Builder(3)}; - assert_parsed_expression_is("1+2+3", Addition::Builder(nAryChildren, 3)); - nAryChildren[2] = Parenthesis::Builder(Addition::Builder(BasedInteger::Builder(3),BasedInteger::Builder(4))); - assert_parsed_expression_is("1+2+(3+4)", Addition::Builder(nAryChildren, 3)); + Expression::Tuple one_two_three = {BasedInteger::Builder(1),BasedInteger::Builder(2),BasedInteger::Builder(3)}; + assert_parsed_expression_is("1+2+3", Addition::Builder(one_two_three)); + assert_parsed_expression_is("1+2+(3+4)", Addition::Builder({BasedInteger::Builder(1), BasedInteger::Builder(2), Parenthesis::Builder(Addition::Builder(BasedInteger::Builder(3),BasedInteger::Builder(4)))})); assert_parsed_expression_is("1×2", Multiplication::Builder(BasedInteger::Builder(1),BasedInteger::Builder(2))); - nAryChildren[2] = BasedInteger::Builder(3); - assert_parsed_expression_is("1×2×3", Multiplication::Builder(nAryChildren, 3)); + assert_parsed_expression_is("1×2×3", Multiplication::Builder(one_two_three)); assert_parsed_expression_is("1+2×3", Addition::Builder(BasedInteger::Builder(1), Multiplication::Builder(BasedInteger::Builder(2), BasedInteger::Builder(3)))); assert_parsed_expression_is("1/2", Division::Builder(BasedInteger::Builder(1),BasedInteger::Builder(2))); assert_parsed_expression_is("(1/2)", Parenthesis::Builder(Division::Builder(BasedInteger::Builder(1),BasedInteger::Builder(2)))); diff --git a/poincare/test/simplification.cpp b/poincare/test/simplification.cpp index 89eb2c287..3438a414d 100644 --- a/poincare/test/simplification.cpp +++ b/poincare/test/simplification.cpp @@ -1318,7 +1318,7 @@ QUIZ_CASE(poincare_simplification_mix) { assert_parsed_expression_simplify_to("(((√(6)-√(2))/4)/((√(6)+√(2))/4))+1", "-√(3)+3"); assert_parsed_expression_simplify_to("1/√(𝐢) × (√(2)-𝐢×√(2))", "-2×𝐢"); // TODO: get rid of complex at denominator? - assert_expression_simplifies_approximates_to("abs(√(300000.0003^23))", "9.7027409010183ᴇ62"); + assert_expression_simplifies_approximates_to("abs(√(300000.0003^23))", "9.702740901018ᴇ62", Degree, Cartesian, 13); } QUIZ_CASE(poincare_hyperbolic_trigonometry) { diff --git a/poincare/test/tree/blob_node.h b/poincare/test/tree/blob_node.h index 6bbd86395..d5584ee73 100644 --- a/poincare/test/tree/blob_node.h +++ b/poincare/test/tree/blob_node.h @@ -13,7 +13,7 @@ public: int data() { return m_data; } virtual int numberOfChildren() const override { return 0; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Blob"; } #endif diff --git a/poincare/test/tree/pair_node.h b/poincare/test/tree/pair_node.h index a6eb9dd06..0d9229eff 100644 --- a/poincare/test/tree/pair_node.h +++ b/poincare/test/tree/pair_node.h @@ -12,7 +12,7 @@ public: virtual size_t size() const override { return sizeof(PairNode); } virtual int numberOfChildren() const override { return 2; } #if POINCARE_TREE_LOG - virtual void logNodeName(std::ostream & stream) const override { + void logNodeName(std::ostream & stream) const override { stream << "Pair"; } #endif diff --git a/python/port/genhdr/qstrdefs.in.h b/python/port/genhdr/qstrdefs.in.h index 5e46e758d..9dbf3f4aa 100644 --- a/python/port/genhdr/qstrdefs.in.h +++ b/python/port/genhdr/qstrdefs.in.h @@ -15,6 +15,7 @@ QCFG(BYTES_IN_LEN, (1)) QCFG(BYTES_IN_HASH, (2)) +<<<<<<< HEAD // Ion QSTR Q(ion) Q(keydown) @@ -188,6 +189,8 @@ Q(time) Q(sleep) Q(monotonic) +======= +>>>>>>> upstream/master // MicroPython QSTRs Q() Q(*) @@ -492,3 +495,176 @@ Q(upper) Q(value) Q(values) Q(zip) + + // Ion QSTR +Q(ion) +Q(keydown) +Q(KEY_LEFT) +Q(KEY_UP) +Q(KEY_DOWN) +Q(KEY_RIGHT) +Q(KEY_OK) +Q(KEY_BACK) +Q(KEY_HOME) +Q(KEY_ONOFF) +Q(KEY_SHIFT) +Q(KEY_ALPHA) +Q(KEY_XNT) +Q(KEY_VAR) +Q(KEY_TOOLBOX) +Q(KEY_BACKSPACE) +Q(KEY_EXP) +Q(KEY_LN) +Q(KEY_LOG) +Q(KEY_IMAGINARY) +Q(KEY_COMMA) +Q(KEY_POWER) +Q(KEY_SINE) +Q(KEY_COSINE) +Q(KEY_TANGENT) +Q(KEY_PI) +Q(KEY_SQRT) +Q(KEY_SQUARE) +Q(KEY_SEVEN) +Q(KEY_EIGHT) +Q(KEY_NINE) +Q(KEY_LEFTPARENTHESIS) +Q(KEY_RIGHTPARENTHESIS) +Q(KEY_FOUR) +Q(KEY_FIVE) +Q(KEY_SIX) +Q(KEY_MULTIPLICATION) +Q(KEY_DIVISION) +Q(KEY_ONE) +Q(KEY_TWO) +Q(KEY_THREE) +Q(KEY_PLUS) +Q(KEY_MINUS) +Q(KEY_ZERO) +Q(KEY_DOT) +Q(KEY_EE) +Q(KEY_ANS) +Q(KEY_EXE) + +// Kandinsky QSTRs +Q(kandinsky) +Q(color) +Q(draw_string) +Q(fill_rect) +Q(get_pixel) +Q(set_pixel) +Q(wait_vblank) +Q(get_keys) + +// Keys QSTRs +Q(left) +Q(up) +Q(down) +Q(right) +Q(OK) +Q(back) + +Q(home) +Q(onOff) +Q(shift) +Q(alpha) +Q(xnt) +Q(var) +Q(toolbox) +Q(backspace) + +Q(exp) +Q(ln) +Q(log) +Q(imaginary) +Q(comma) +Q(power) + +Q(sin) +Q(cos) +Q(tan) +Q(pi) +Q(sqrt) +Q(square) + +Q(7) +Q(8) +Q(9) +Q(() +Q()) + +Q(4) +Q(5) +Q(6) +Q(*) +Q(/) + +Q(1) +Q(2) +Q(3) +Q(+) +Q(-) + +Q(0) +Q(.) +Q(EE) +Q(Ans) +Q(EXE) + +// Matplotlib QSTRs +Q(arrow) +Q(axis) +Q(bar) +Q(grid) +Q(grid) +Q(hist) +Q(plot) +Q(matplotlib) +Q(matplotlib.pyplot) +Q(pyplot) +Q(scatter) +Q(show) +Q(text) + +// Turtle QSTRs +Q(turtle) +Q(forward) +Q(fd) +Q(backward) +Q(bk) +Q(back) +Q(right) +Q(rt) +Q(left) +Q(lt) +Q(goto) +Q(setpos) +Q(setposition) +Q(setheading) +Q(seth) +Q(circle) +Q(speed) +Q(position) +Q(pos) +Q(heading) +Q(pendown) +Q(pd) +Q(down) +Q(penup) +Q(pu) +Q(up) +Q(pensize) +Q(width) +Q(isdown) +Q(pencolor) +Q(reset) +Q(showturtle) +Q(st) +Q(hideturtle) +Q(ht) +Q(isvisible) + +// utime QSTRs +Q(time) +Q(sleep) +Q(monotonic) diff --git a/python/port/mod/matplotlib/pyplot/modpyplot.cpp b/python/port/mod/matplotlib/pyplot/modpyplot.cpp index e8bfff604..4381c2520 100644 --- a/python/port/mod/matplotlib/pyplot/modpyplot.cpp +++ b/python/port/mod/matplotlib/pyplot/modpyplot.cpp @@ -114,7 +114,11 @@ mp_obj_t modpyplot_axis(size_t n_args, const mp_obj_t *args) { } else { mp_raise_ValueError("Unrecognized string given to axis; try 'on', 'off' or 'auto'"); } -#warning Use mp_obj_is_bool when upgrading uPy +#if MICROPY_OBJ_IMMEDIATE_OBJS +/* This couldn't be done at the time of writing because mp_obj_is_bool didn't + * exist just yet. */ +#error Use mp_obj_is_bool instead of mp_obj_is_type +#endif } else if (mp_obj_is_type(arg, &mp_type_bool)) { sPlotStore->setAxesRequested(mp_obj_is_true(arg)); } else if (mp_obj_is_type(arg, &mp_type_tuple) || mp_obj_is_type(arg, &mp_type_list)) { diff --git a/python/port/mod/matplotlib/pyplot/plot_store.cpp b/python/port/mod/matplotlib/pyplot/plot_store.cpp index 9647044b6..de5996894 100644 --- a/python/port/mod/matplotlib/pyplot/plot_store.cpp +++ b/python/port/mod/matplotlib/pyplot/plot_store.cpp @@ -1,4 +1,5 @@ #include "plot_store.h" +#include namespace Matplotlib { @@ -160,15 +161,12 @@ void PlotStore::addLabel(mp_obj_t x, mp_obj_t y, mp_obj_t string) { // Axes -static inline float minFloat(float x, float y) { return x < y ? x : y; } -static inline float maxFloat(float x, float y) { return x > y ? x : y; } - void updateRange(float * xMin, float * xMax, float * yMin, float * yMax, float x, float y) { if (!std::isnan(x) && !std::isinf(x) && !std::isnan(y) && !std::isinf(y)) { - *xMin = minFloat(*xMin, x); - *xMax = maxFloat(*xMax, x); - *yMin = minFloat(*yMin, y); - *yMax = maxFloat(*yMax, y); + *xMin = std::min(*xMin, x); + *xMax = std::max(*xMax, x); + *yMin = std::min(*yMin, y); + *yMax = std::max(*yMax, y); } } diff --git a/python/port/mod/matplotlib/pyplot/plot_view.cpp b/python/port/mod/matplotlib/pyplot/plot_view.cpp index 76daa005a..4da55f8cf 100644 --- a/python/port/mod/matplotlib/pyplot/plot_view.cpp +++ b/python/port/mod/matplotlib/pyplot/plot_view.cpp @@ -1,4 +1,5 @@ #include "plot_view.h" +#include namespace Matplotlib { @@ -52,7 +53,6 @@ void PlotView::traceSegment(KDContext * ctx, KDRect r, PlotStore::Segment segmen } } -static inline KDCoordinate maxKDCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } void PlotView::traceRect(KDContext * ctx, KDRect r, PlotStore::Rect rect) const { KDCoordinate left = std::round(floatToPixel(Axis::Horizontal, rect.left())); KDCoordinate right = std::round(floatToPixel(Axis::Horizontal, rect.right())); @@ -61,7 +61,7 @@ void PlotView::traceRect(KDContext * ctx, KDRect r, PlotStore::Rect rect) const KDRect pixelRect( left, top, - maxKDCoordinate(right - left, 1), // Rectangle should at least be visible + std::max(right - left, 1), // Rectangle should at least be visible bottom - top ); ctx->fillRect(pixelRect, rect.color()); @@ -76,5 +76,4 @@ void PlotView::traceLabel(KDContext * ctx, KDRect r, PlotStore::Label label) con ); } - } diff --git a/python/port/mod/turtle/turtle.cpp b/python/port/mod/turtle/turtle.cpp index 58b51c4c2..1a5c3abc2 100644 --- a/python/port/mod/turtle/turtle.cpp +++ b/python/port/mod/turtle/turtle.cpp @@ -73,7 +73,7 @@ void Turtle::left(mp_float_t angle) { void Turtle::circle(mp_int_t radius, mp_float_t angle) { mp_float_t oldHeading = heading(); - mp_float_t length = (angle > 0 ? 1 : -1) * angle * k_headingScale * radius; + mp_float_t length = std::fabs(angle * k_headingScale * radius); if (length > 1) { for (int i = 1; i < length; i++) { mp_float_t progress = i / length; @@ -82,7 +82,7 @@ void Turtle::circle(mp_int_t radius, mp_float_t angle) { // Keyboard interruption. Return now to let MicroPython process it. return; } - setHeadingPrivate(oldHeading+angle*progress); + setHeadingPrivate(oldHeading+std::copysign(angle*progress, radius)); } forward(1); setHeading(oldHeading+angle); @@ -377,7 +377,7 @@ void Turtle::drawPaw(PawType type, PawPosition pos) { assert(m_underneathPixelBuffer != nullptr); KDCoordinate pawOffset = 5; constexpr float crawlOffset = 0.6f; - constexpr float angles[] = {M_PI_2/2, M_PI_2+M_PI_2/2, -M_PI_2-M_PI_2/2, -M_PI_2/2}; + constexpr float angles[] = {M_PI_4, 3*M_PI_4, -3*M_PI_4, -M_PI_4}; // Compute the paw offset from the turtle center float currentAngle = angles[(int) type];