Advertisement
Guest User

Untitled

a guest
Feb 24th, 2020
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.38 KB | None | 0 0
  1. #ifndef __STREAM_TABLE_H
  2. #define __STREAM_TABLE_H
  3.  
  4. #undef max
  5. #undef min
  6.  
  7. #include <string>
  8. #include <vector>
  9. #include <algorithm>
  10. #include <iostream>
  11. #include <cstring>
  12.  
  13. //стратегия формирования единой таблицы
  14. #define CRLF "\n"
  15.  
  16. //стратегия построчной выгрузки таблицы
  17. //#define CRLF std::endl
  18.  
  19. /**
  20. * Прямоугольная таблица с разделителями строк и столбцов
  21. * Синтаксис как у потоков C++
  22. */
  23. class StreamTable {
  24. public:
  25.     std::ostream &os_;
  26.  
  27.     StreamTable(std::ostream &os = std::cout, char delimRow = ' ', char delimCol = ' ') :
  28.             borderExtOn_(true),
  29.             delimRowOn_(true),
  30.             delimRow_(delimRow),
  31.             delimColOn_(true),
  32.             delimCol_(delimCol),
  33.             os_(os),
  34.             colIndex_(0),
  35.             firstCell_(1) {}
  36.  
  37.     virtual ~StreamTable() {}
  38.  
  39.     virtual std::ostream &os() const {
  40.         return os_;
  41.     }
  42.  
  43.     //отображать внешние границы?
  44.     void MakeBorderExt(bool on) {
  45.         borderExtOn_ = on;
  46.     }
  47.  
  48.     //символ разделителя строк
  49.     void SetDelimRow(bool delimOn, char delimRow = ' ') {
  50.         delimRowOn_ = delimOn;
  51.         if (delimRowOn_)
  52.             delimRow_ = delimRow;
  53.         else if (!delimColOn_)
  54.             MakeBorderExt(false);
  55.     }
  56.  
  57.     //символ разделителя столбцов
  58.     void SetDelimCol(bool delimOn, char delimCol = ' ') {
  59.         delimColOn_ = delimOn;
  60.         if (delimColOn_)
  61.             delimCol_ = delimCol;
  62.         else if (!delimRowOn_)
  63.             MakeBorderExt(false);
  64.     }
  65.  
  66.     int AddCol(int colWidth, bool visible = true) {
  67.         colWidth_.push_back(colWidth);
  68.         visible_.push_back(visible);
  69.         return colWidth_.back();
  70.     }
  71.  
  72.     void SetVisible(int col, bool flg) {
  73.         visible_[col - 1] = flg;
  74.     }
  75.  
  76.     void SetCols(int colCount, int colWidth = 0) {
  77.         Clear();
  78.  
  79.         for (int ic = 0; ic < colCount; ic++) {
  80.             AddCol(colWidth);
  81.         }
  82.     }
  83.  
  84.     virtual void Clear() {
  85.         colWidth_.clear();
  86.         visible_.clear();
  87.         colIndex_ = 0;
  88.         firstCell_ = 1;
  89.     }
  90.  
  91.     void AddEmptyRow() {
  92.         for (int ic = 0; ic < (int)colWidth_.size(); ic++) {
  93.             *this << "";
  94.         }
  95.     }
  96.  
  97.     template <typename T> StreamTable &operator << (const T &obj) {
  98.         Push(obj);
  99.         return *this;
  100.     }
  101.  
  102.     StreamTable &operator << (const std::string &s) {
  103.         colWidth_[colIndex_] = std::max(colWidth_[colIndex_], (int)s.size() + 1);
  104.         Push(s);
  105.         return *this;
  106.     }
  107.  
  108.     StreamTable &operator << (const char *s) {
  109.         colWidth_[colIndex_] = std::max(colWidth_[colIndex_], (int)strlen(s) + 1);
  110.         Push(s);
  111.         return *this;
  112.     }
  113.  
  114. protected:
  115.     int colIndex_;
  116.  
  117. private:
  118.     bool borderExtOn_;
  119.     bool delimRowOn_;
  120.     char delimRow_;
  121.  
  122.     bool delimColOn_;
  123.     char delimCol_;
  124.  
  125.     std::vector<int> colWidth_;
  126.     bool firstCell_;
  127.     std::vector<int> visible_;
  128.  
  129.     template <typename T>
  130.     void Push(const T &obj) {
  131.         if (firstCell_) {
  132.             if (borderExtOn_)
  133.                 MakeRowBorder();
  134.  
  135.             firstCell_ = 0;
  136.         }
  137.  
  138.         if (visible_[colIndex_]) {
  139.             DelimCol();
  140.  
  141.             os_.width(colWidth_[colIndex_]);
  142.             os_.fill(' ');
  143.             os_ << /*std::setiosflags(std::ios::left) << */obj;
  144.         }
  145.  
  146.         if (++colIndex_ == (int)colWidth_.size()) {
  147.             DelimCol();
  148.  
  149.             if (delimRowOn_)
  150.                 MakeRowBorder();
  151.             else
  152.                 os_ << CRLF;
  153.  
  154.             colIndex_ = 0;
  155.         }
  156.     }
  157.  
  158.     void MakeRowBorder() {
  159.         os_ << CRLF;
  160.         DelimCol();
  161.  
  162.         int ic;
  163.         for (ic = 0; ic < (int)colWidth_.size(); ic++) {
  164.             if (visible_[ic]) {
  165.                 os_.width(colWidth_[ic] + 1);
  166.                 os_.fill(delimRow_);
  167.                 DelimCol();
  168.             }
  169.         }
  170.         os_ << CRLF;
  171.     }
  172.  
  173.     void DelimCol() {
  174.         if (delimColOn_ && (borderExtOn_ || colIndex_))
  175.             os_ << delimCol_;
  176.         else
  177.             os_ << ' ';
  178.     }
  179.  
  180.     //запрет на копирование
  181.     StreamTable &operator = (const StreamTable &);
  182. };
  183.  
  184. #endif // __STREAM_TABLE_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement