-
Notifications
You must be signed in to change notification settings - Fork 0
/
formula.h
65 lines (54 loc) · 4.48 KB
/
formula.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#pragma once
#include "common.h"
#include <memory>
#include <vector>
// Формула, позволяющая вычислять и обновлять арифметическое выражение.
// Поддерживаемые возможности:
// * Простые бинарные операции и числа, скобки: 1+2*3, 2.5*(2+3.5/7)
// * Значения ячеек в качестве переменных: A1+B2*C3
// Ячейки указанные в формуле могут быть как формулами, так и текстом. Если это
// текст, но он представляет число, тогда его нужно трактовать как число. Пустая
// ячейка или ячейка с пустым текстом трактуется как число ноль.
class IFormula {
public:
using Value = std::variant<double, FormulaError>;
// Как вставка/удаление строк/столбцов повлияла на формулу
enum class HandlingResult {
NothingChanged, // Никак не повлияла
ReferencesRenamedOnly, // Названия некоторых ячеек обновились, но логически
// это те же самые ячейки
ReferencesChanged // Изменился набор ячеек (была удалена ячейка, на которую
// была непосредственная ссылка)
};
virtual ~IFormula() = default;
// Возвращает вычисленное значение формулы для переданного листа, либо ошибку.
// Если вычисление какой-то из указанных в формуле ячеек приводит к ошибке, то
// возвращается именно эта ошибка. Если таких ошибок несколько, возвращается
// любая.
virtual Value Evaluate(const ISheet& sheet) const = 0;
// Возвращает выражение, которое описывает формулу.
// Не содержит пробелов и лишних скобок.
virtual std::string GetExpression() const = 0;
// Возвращает список ячеек, которые непосредственно задействованы в вычислении
// формулы. Список отсортирован по возрастанию и не содержит повторяющихся
// ячеек.
virtual std::vector<Position> GetReferencedCells() const = 0;
// Обновляет формулу при вставке заданного числа строк/столбцов перед
// строкой/столбцом с заданным индексом.
// Все ссылки обновляются таким образом, чтобы указывать на те же ячейки, что
// и до вставки. Обновляется как сама формула, так и её выражение.
virtual HandlingResult HandleInsertedRows(int before, int count = 1) = 0;
virtual HandlingResult HandleInsertedCols(int before, int count = 1) = 0;
// Обновляет формулу при удалении заданного числа строк/столбцов, начиная со
// строки/столбца с заданным индексом.
// Все ссылки обновляются таким образом, чтобы указывать на те же ячейки, что
// и до вставки. Обновляется как сама формула, так и её выражение.
// Если формула содержала ссылку на удалённую ячейку, то эта ссылка в
// выражении должна замениться на строку, соответствующую ошибке
// FormulaError::Ref. Попытка вычислить такую формулу вернёт эту же ошибку.
virtual HandlingResult HandleDeletedRows(int first, int count = 1) = 0;
virtual HandlingResult HandleDeletedCols(int first, int count = 1) = 0;
};
// Парсит переданное выражение и возвращает объект формулы.
// Бросает FormulaException в случае если формула синтаксически некорректна.
std::unique_ptr<IFormula> ParseFormula(std::string expression);