Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <vector>
- #include <forward_list>
- #include <cstdlib>
- using namespace std;
- enum Type { T_Cell, T_Plus, T_Minus, T_Mult, T_Div, T_UnMinus, T_Value };
- template <class T>
- class Cell
- {
- struct CellStruct
- {
- Type type;
- union
- {
- T value;
- const Cell* cell;
- };
- CellStruct(const Cell* c) : type(T_Cell), cell(c) {}
- CellStruct(T v) : type(T_Value), value(v) {}
- CellStruct(Type t) : type(t), value(0) {}
- };
- forward_list<CellStruct> operations;
- using iterator = typename forward_list<CellStruct>::const_iterator;
- Cell& operator <<(Type op) { operations.emplace_front(op); return *this; }
- Cell& operator <<(T value) { operations.emplace_front(value); return *this; }
- Cell& operator <<(const Cell& value) { operations.emplace_front(&value); return *this; }
- Cell& operator <<(Cell &&value) { operations.splice_after(operations.before_begin(), forward_list<CellStruct>(value.operations)); return *this; }
- Cell& Clear() { operations.clear(); return *this; }
- template <class U, class V>
- Cell(U &&first, V &&second, Type op)
- {
- *this << forward<V>(second) << forward<U>(first) << op;
- }
- T Calc(iterator& it) const
- {
- switch (it->type)
- {
- case T_Cell: return (T)*(it++)->cell;
- case T_Plus: return ++it, Calc(it) + Calc(it);
- case T_Minus: return ++it, Calc(it) - Calc(it);
- case T_Mult: return ++it, Calc(it) * Calc(it);
- case T_Div: return ++it, Calc(it) / Calc(it);
- case T_UnMinus: return -Calc(++it);
- case T_Value: return (it++)->value;
- default: exit(1);
- }
- }
- public:
- explicit operator T() const {
- iterator start = operations.cbegin();
- return Calc(start);
- }
- Cell() {}
- Cell(T value) { *this << value; }
- template <class U> Cell& operator =(U&& val) { Clear(); return *this << forward<U>(val); }
- Cell operator-() const & { Cell ret; return ret << *this << T_UnMinus; }
- Cell operator-() && { return *this << T_UnMinus; }
- template <class U, class V> friend auto operator +(U &&first, V &&second)->Cell<T> { return Cell<T>(forward<U>(first), forward<V>(second), T_Plus); }
- template <class U, class V> friend auto operator -(U &&first, V &&second)->Cell<T> { return Cell<T>(forward<U>(first), forward<V>(second), T_Minus); }
- template <class U, class V> friend auto operator *(U &&first, V &&second)->Cell<T> { return Cell<T>(forward<U>(first), forward<V>(second), T_Mult); }
- template <class U, class V> friend auto operator /(U &&first, V &&second)->Cell<T> { return Cell<T>(forward<U>(first), forward<V>(second), T_Div); }
- template <class U> auto operator +=(U &&other)->Cell<T> { return *this << forward<U>(other) << T_Plus; }
- template <class U> auto operator -=(U &&other)->Cell<T> { return *this << forward<U>(other) << T_Minus; }
- template <class U> auto operator *=(U &&other)->Cell<T> { return *this << forward<U>(other) << T_Mult; }
- template <class U> auto operator /=(U &&other)->Cell<T> { return *this << forward<U>(other) << T_Div; }
- };
- template <class T>
- class SuperCalc
- {
- vector<vector<Cell<T>>> _data;
- public:
- SuperCalc(int m, int n) : _data(m,vector<Cell<T>>(n, 0)) {}
- Cell<T>& operator() (int i, int j)
- {
- return _data[i][j];
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement