Created
December 14, 2012 11:43
Revisions
-
mpusz revised this gist
Dec 15, 2012 . 1 changed file with 27 additions and 22 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,7 +7,6 @@ #include <array> #include <iostream> #include <cassert> // -------------------- TOOLS --------------------- @@ -18,6 +17,12 @@ inline std::unique_ptr<T> make_unique(Args&&... args) return std::unique_ptr<T>(new T{std::forward<Args>(args)...}); } class CNonCopyable { public: CNonCopyable() = default; CNonCopyable(const CNonCopyable &) = delete; CNonCopyable &operator=(const CNonCopyable &) = delete; }; // -------------------- FRAMEWORK --------------------- @@ -34,16 +39,16 @@ namespace spreadsheet { { _cells.at(row).at(col) = std::move(expr); } const CExpression<T> &Expression(std::size_t row, std::size_t col) const { auto &cell = _cells.at(row).at(col); if(!cell) throw std::runtime_error("No expression in cell(row: " + std::to_string(row) + ", " + std::to_string(col) + ")"); return *cell; } T operator()(std::size_t row, std::size_t col) const { return Expression(row, col).Value(); } @@ -52,7 +57,7 @@ namespace spreadsheet { template<typename T> class CExpression : CNonCopyable { public: virtual ~CExpression() = default; virtual T Value() const = 0; @@ -76,15 +81,15 @@ namespace spreadsheet { public: CExpressionBinary(std::unique_ptr<CExpression<T> > left, std::unique_ptr<CExpression<T> > right): _left(move(left)), _right(move(right)) {} T Value() const override { return EXPR<T>()(_left->Value(), _right->Value()); } }; template<typename T> using CExpressionAdd = CExpressionBinary<T, std::plus>; template<typename T> using CExpressionSubtract = CExpressionBinary<T, std::minus>; template<typename T> using CExpressionMultiply = CExpressionBinary<T, std::multiplies>; template<typename T> using CExpressionDivide = CExpressionBinary<T, std::divides>; template<typename T, std::size_t ROWS, std::size_t COLS> class CExpressionCell : public CExpression<T> { const CSpreadsheet<T, ROWS, COLS> &_spreadsheet; @@ -93,7 +98,7 @@ namespace spreadsheet { public: CExpressionCell(const CSpreadsheet<T, ROWS, COLS> &spreadsheet, std::size_t row, std::size_t col): _spreadsheet(spreadsheet), _row(row), _col(col) {} T Value() const override { return _spreadsheet(_row, _col); } }; } @@ -118,31 +123,31 @@ int main() { try { CSpreadsheet sheet; // sheet(ROWS, COLS); // should throw // sheet(1, 1); // should throw sheet.Expression(0, 0, make_unique<CExpressionConstant>(5.0)); assert(sheet(0, 0) == 5); sheet.Expression(0, 1, make_unique<CExpressionAdd>(make_unique<CExpressionConstant>(10.0), make_unique<CExpressionCell>(sheet, 0, 0))); assert(sheet(0, 1) == 15); sheet.Expression(0, 2, make_unique<CExpressionDivide>(make_unique<CExpressionCell>(sheet, 0, 1), make_unique<CExpressionCell>(sheet, 0, 0))); assert(sheet(0, 2) == 3); // override last cell and set an expression for not filled one sheet.Expression(0, 2, make_unique<CExpressionCell>(sheet, 0, 3)); // sheet(0, 2); // should throw sheet.Expression(0, 3, make_unique<CExpressionMultiply>(make_unique<CExpressionConstant>(2.0), make_unique<CExpressionSubtract>(make_unique<CExpressionCell>(sheet, 0, 1), make_unique<CExpressionCell>(sheet, 0, 0)))); assert(sheet(0, 3) == 20); // check now assert(sheet(0, 2) == sheet(0, 3)); } catch(const std::exception &ex) { std::cerr << "ERROR: " << ex.what() << "\n"; -
mpusz renamed this gist
Dec 15, 2012 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
mpusz created this gist
Dec 14, 2012 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,150 @@ // // author: Mateusz Pusz // #include <functional> #include <memory> #include <array> #include <iostream> #include <cassert> #include <boost/noncopyable.hpp> // -------------------- TOOLS --------------------- template<typename T, typename ...Args> inline std::unique_ptr<T> make_unique(Args&&... args) { return std::unique_ptr<T>(new T{std::forward<Args>(args)...}); } // -------------------- FRAMEWORK --------------------- namespace spreadsheet { template<typename T> class CExpression; template<typename T, std::size_t ROWS, std::size_t COLS> class CSpreadsheet { std::array<std::array<std::unique_ptr<CExpression<T> >, COLS>, ROWS> _cells; public: void Expression(std::size_t row, std::size_t col, std::unique_ptr<CExpression<T> > expr) { _cells.at(row).at(col) = std::move(expr); } const CExpression<T> &Expression(std::size_t row, std::size_t col) const { auto &cell = _cells.at(row).at(col); if(!cell) throw std::runtime_error("No expression in cell(row: " + std::to_string(row) + ", " + std::to_string(col) + ")"); return *cell; } T Value(std::size_t row, std::size_t col) const { return Expression(row, col).Value(); } }; template<typename T> class CExpression : boost::noncopyable { public: virtual ~CExpression() = default; virtual T Value() const = 0; }; template<typename T> class CExpressionConstant : public CExpression<T> { T _value; public: CExpressionConstant(T value): _value(std::move(value)) {} T Value() const override { return _value; } }; // note: template template used here :-) template<typename T, template<class> class EXPR> class CExpressionBinary : public CExpression<T> { std::unique_ptr<CExpression<T> > _left; std::unique_ptr<CExpression<T> > _right; public: CExpressionBinary(std::unique_ptr<CExpression<T> > left, std::unique_ptr<CExpression<T> > right): _left(move(left)), _right(move(right)) {} T Value() const override { return EXPR()(_left->Value(), _right->Value()); } }; template<typename T> using CExpressionAdd = CExpressionBinary<T, std::plus>; template<typename T> using CExpressionSubtract = CExpressionBinary<T, std::minus>; template<typename T> using CExpressionMultiply = CExpressionBinary<T, std::multiplies>; template<typename T> using CExpressionDivide = CExpressionBinary<T, std::divides>; template<typename T, std::size_t ROWS, std::size_t COLS> class CExpressionCell : public CExpression<T> { const CSpreadsheet<T, ROWS, COLS> &_spreadsheet; const std::size_t _row; const std::size_t _col; public: CExpressionCell(const CSpreadsheet<T, ROWS, COLS> &spreadsheet, std::size_t row, std::size_t col): _spreadsheet(spreadsheet), _row(row), _col(col) {} T Value() const override { return _spreadsheet.Value(_row, _col); } }; } // -------------------- USAGE --------------------- using Value = double; constexpr std::size_t ROWS = 10; constexpr std::size_t COLS = 10; using CSpreadsheet = spreadsheet::CSpreadsheet<Value, ROWS, COLS>; using CExpressionConstant = spreadsheet::CExpressionConstant<Value>; using CExpressionAdd = spreadsheet::CExpressionAdd<Value>; using CExpressionSubtract = spreadsheet::CExpressionSubtract<Value>; using CExpressionMultiply = spreadsheet::CExpressionMultiply<Value>; using CExpressionDivide = spreadsheet::CExpressionDivide<Value>; using CExpressionCell = spreadsheet::CExpressionCell<Value, ROWS, COLS>; int main() { try { CSpreadsheet sheet; // sheet.Value(ROWS, COLS); // should throw // sheet.Value(1, 1); // should throw sheet.Expression(0, 0, make_unique<CExpressionConstant>(5.0)); assert(sheet.Value(0, 0) == 5); sheet.Expression(0, 1, make_unique<CExpressionAdd>(make_unique<CExpressionConstant>(10.0), make_unique<CExpressionCell>(sheet, 0, 0))); assert(sheet.Value(0, 1) == 15); sheet.Expression(0, 2, make_unique<CExpressionDivide>(make_unique<CExpressionCell>(sheet, 0, 1), make_unique<CExpressionCell>(sheet, 0, 0))); assert(sheet.Value(0, 2) == 3); // override last cell and set an expression for not filled one sheet.Expression(0, 2, make_unique<CExpressionCell>(sheet, 0, 3)); // sheet.Value(0, 2); // should throw sheet.Expression(0, 3, make_unique<CExpressionMultiply>(make_unique<CExpressionConstant>(2.0), make_unique<CExpressionSubtract>(make_unique<CExpressionCell>(sheet, 0, 1), make_unique<CExpressionCell>(sheet, 0, 0)))); assert(sheet.Value(0, 3) == 20); // check now assert(sheet.Value(0, 2) == sheet.Value(0, 3)); } catch(const std::exception &ex) { std::cerr << "ERROR: " << ex.what() << "\n"; } }