#include #include #include #include #include class Report { public: enum opcode { // opcodes declaration STRING, COLUMN, NEWLINE, ROW, INTEGER }; // Constructor Report() : header(), header_strings(), body(), body_strings() { } // Mutator void AddToHeader(opcode to_add) { assert(to_add != STRING); header.push_back(to_add); } // Mutator. void AddToHeader(std::string to_add) { header_strings[header.size()] = to_add; header.push_back(STRING); } // Mutator void AddToBody(opcode to_add) { assert(to_add != STRING); body.push_back(to_add); } // Mutator. void AddToBody(std::string to_add) { body_strings[body.size()] = to_add; body.push_back(STRING); } void Print(int start, int stop, int step) { // interpretive state (e.g. registers) int current = start; int column = 0; int row = 0; // interpretive loop for (int i = 0; i < header.size(); ++i) { // interpretive dispatch switch (header[i]) { case STRING: std::cout << header_strings[i]; break; case COLUMN: std::cout << column; column += 1; break; case NEWLINE: std::cout << std::endl; column = 0; row += 1; break; case ROW: std::cout << row; break; case INTEGER: std::cout << current; current += step; break; default: assert(false); break; } } // interpretive loop while (current < stop) { // interpretive loop for (int i = 0; i < body.size(); ++i) { // interpretive dispatch switch (body[i]) { case STRING: std::cout << body_strings[i]; break; case COLUMN: std::cout << column; column += 1; break; case NEWLINE: std::cout << std::endl; column = 0; row += 1; break; case ROW: std::cout << row; break; case INTEGER: std::cout << current; current += step; break; default: assert(false); break; } } } } private: std::vector header; std::map header_strings; std::vector body; std::map body_strings; }; int main(int argc, char* argv[]) { Report the_report; // program the_report.AddToHeader("\tcol"); the_report.AddToHeader(Report::COLUMN); the_report.AddToHeader("\tcol"); the_report.AddToHeader(Report::COLUMN); the_report.AddToHeader("\tcol"); the_report.AddToHeader(Report::COLUMN); the_report.AddToHeader(Report::NEWLINE); the_report.AddToBody("row"); the_report.AddToBody(Report::ROW); the_report.AddToBody(":\t"); the_report.AddToBody(Report::INTEGER); the_report.AddToBody(",\t"); the_report.AddToBody(Report::INTEGER); the_report.AddToBody(",\t"); the_report.AddToBody(Report::INTEGER); the_report.AddToBody(",\t"); the_report.AddToBody(Report::NEWLINE); the_report.Print(10, 30, 3); return 0; }