From 97a4861cafceee5f1b53e8897866270b173cabea Mon Sep 17 00:00:00 2001 From: Daher Alfawares Date: Thu, 30 Nov 2023 12:29:57 -0800 Subject: [PATCH] Update x_table.hpp --- x_table.hpp | 363 ++++++++++++++++++++++++---------------------------- 1 file changed, 164 insertions(+), 199 deletions(-) diff --git a/x_table.hpp b/x_table.hpp index c72daeb..e6f096f 100644 --- a/x_table.hpp +++ b/x_table.hpp @@ -1,7 +1,7 @@ //C++ ////////////////////////////////////////////////////////////////////////////// // // -// Filename : x_table.hpp // +// Filename : ASCII_Table.hpp // // Created by : Daher Alfawares // // Created Date : 06/20/2009 // // License : Apache License 2.0 // @@ -24,7 +24,7 @@ /* - X Table is a C++ class that allows you to format your data in an ASCII dynamic table structure. + ASCII Table is a C++ class that allows you to format your data in an ASCII dynamic table structure. Example: @@ -48,9 +48,8 @@ */ - -#ifndef _X_Table__0a61eabe_d038_4d30_a6fb_e202b2dfd6a9 -#define _X_Table__0a61eabe_d038_4d30_a6fb_e202b2dfd6a9 +#ifndef _DA_ASCII_Table__0a61eabe_d038_4d30_a6fb_e202b2dfd6a9 +#define _DA_ASCII_Table__0a61eabe_d038_4d30_a6fb_e202b2dfd6a9 #include #include @@ -59,265 +58,231 @@ #include #include -namespace x -{ - // forward: - - // the following allows adding a C style string to an std::string and returns an std::string. - // example: - // std::string a = "abc"; - // std::string b = "123" + a; - // - - inline std::string operator + ( const char*a, const std::string& b ); - inline std::string itoa( const int &i ); - inline int atoi( const std::string&s ); - - // lexical cast. - template class lexical_cast; +namespace x { + inline std::string operator + (const char* a, const std::string& b); + inline std::string itoa(const int& i); + inline int atoi(const std::string& s); + + template + class lexical_cast; + struct scoped_mute_s; - // formats the output. - std::size_t length( std::string _String); + + std::size_t length(std::string _String); std::string fill(std::string _Str, std::size_t _Size); - + class endl {}; - class table - { + + class table { public: - std::string title; - size_t column; - std::vector columns; - std::vector column_widths; - std::string comment; - std::string Prefix; // line prefix. - - table( std::string t ):title(t),column(0){} - - - std::vector< std::vector > rows; - - table & operator<<(std::string t){ + std::string title; + size_t column; + std::vector columns; + std::vector column_widths; + std::string comment; + std::string Prefix; + + table(std::string t) : title(t), column(0) {} + + std::vector> rows; + + table& operator<<(std::string t) { return (*this)(t); } - table & operator<<(int t){ + + table& operator<<(int t) { std::stringstream fstr; fstr << t; - return (*this)<< fstr.str(); + return (*this) << fstr.str(); } - table & operator()(std::string t) - { - if( column >= columns.size() ) - { + + table& operator()(std::string t) { + if (column >= columns.size()) { columns.push_back(""); column_widths.push_back(0); } - + columns[column] = t; - if( column_widths[column] < length(t) ) - column_widths[column] = length(t); - + if (column_widths[column] < length(t)) column_widths[column] = length(t); + ++column; - + return *this; } - table & operator()(int i) - { + + table& operator()(int i) { return (*this)(itoa(i)); } - - void operator ++(int) - { + + void operator++(int) { column = 0; - rows.push_back( columns ); + rows.push_back(columns); } - - std::string prefix(){ return Prefix; } - void prefix( std::string _P ){ Prefix=_P; } - - std::string endl(){ return "\r\n" + prefix() + " "; } + + std::string prefix() { return Prefix; } + void prefix(std::string _P) { Prefix = _P; } + + std::string endl() { return "\r\n" + prefix() + " "; } }; - - inline std::ostream& operator << ( std::ostream& _Str, table& T ) - { - - int width = std::accumulate( T.column_widths.begin(), T.column_widths.end(), 0 ); - width += 3*T.columns.size(); - + + inline std::ostream& operator<<(std::ostream& _Str, table& T) { + // Calculate total width of the table + int width = std::accumulate(T.column_widths.begin(), T.column_widths.end(), 0); + width += 3 * (T.columns.size() - 1) + 4; // Adding space for separators and borders _Str << std::setiosflags(std::ios::left); - _Str << T.endl(); - - // top border. -// _Str -// << ' '; -// for( int b=0; b< width-1; b++ ) -// _Str -// << '-'; -// _Str -// << ' ' -// << T.endl(); - - // title. - _Str - << " " - << std::setw(width-1) - << T.title - << "" - << T.endl(); - - // middle border - for( size_t i=0; i< T.columns.size(); i++ ) - _Str - << " " - << std::setw( static_cast(T.column_widths[i]) ) - << std::setfill('-') - << "" + + // top border + _Str << '+'; + for (int b = 0; b < width - 2; b++) + _Str << '-'; + _Str << '+' + << T.endl(); + + // title + _Str << "|" + << std::setw(width - 2) << std::setfill(' ') - << " "; - _Str - << " " - << T.endl(); - - - if( !T.rows.empty() || !T.rows[0].empty() ) - { - size_t i=0,j=0; - - // first row as header. - for( i=0; i< T.columns.size(); i++ ) - { - _Str - << " " - << fill( T.rows[j][i], T.column_widths[i] ) - << " "; - } - _Str - << " " + << T.title + << "|" << T.endl(); - - // middle border - for( size_t i=0; i< T.columns.size(); i++ ) - { - _Str - << " " - << std::setw( static_cast(T.column_widths[i]) ) - << std::setfill(' ') + + // middle border + for (size_t i = 0; i < T.columns.size(); i++) { + _Str << "+-" + << std::setw(static_cast(T.column_widths[i])) + << std::setfill('-') << "" << std::setfill(' ') - << " "; - } - _Str - << " " + << "-"; + } + _Str << "+" << T.endl(); - + + // rest of the table + if (!T.rows.empty() || !T.rows[0].empty()) { + size_t i = 0, j = 0; + + // first row as header. + for (i = 0; i < T.columns.size(); i++) + _Str << "| " + << fill(T.rows[j][i], T.column_widths[i]) + << " "; + _Str << "|" + << T.endl(); + + // middle border + for (size_t i = 0; i < T.columns.size(); i++) + _Str << "+-" + << std::setw(static_cast(T.column_widths[i])) + << std::setfill('-') + << "" + << std::setfill(' ') + << "-"; + _Str << "+" + << T.endl(); + // comment if available. - if( !T.comment.empty() ) - _Str - << " " - << std::setw(width-1) - << T.comment - << " " - << T.endl(); - + if (!T.comment.empty()) + _Str << "|" + << std::setw(width - 1) + << T.comment + << "|" + << T.endl(); + // full table. - for( size_t j=1; j< T.rows.size(); j++ ) - { - for( size_t i=0; i< T.columns.size(); i++ ) - { - _Str - << " " - << fill( T.rows[j][i], T.column_widths[i] ) - << " "; - } - _Str - << " " - << T.endl(); + for (size_t j = 1; j < T.rows.size(); j++) { + for (size_t i = 0; i < T.columns.size(); i++) + _Str << "| " + << fill(T.rows[j][i], T.column_widths[i]) + << " "; + _Str << "|" + << T.endl(); } } - + // bottom border. - for( size_t i=0; i< T.columns.size(); i++ ) - { - _Str - << " " - << std::setw( static_cast(T.column_widths[i]) ) - << std::setfill('-') - << "" - << std::setfill(' ') - << " "; - } - _Str << std::resetiosflags(std::ios::left); - _Str - << " " - << std::endl; - + for (size_t i = 0; i < T.columns.size(); i++) + _Str << "+-" + << std::setw(static_cast(T.column_widths[i])) + << std::setfill('-') + << "" + << std::setfill(' ') + << "-"; + _Str << "+" + << std::resetiosflags(std::ios::left) + << std::endl; + return _Str; } - - inline std::string operator + ( const char*a, const std::string& b ) - { + + inline std::string operator+(const char* a, const std::string& b) { std::string c; c += a; c += b; return c; } - - inline std::string itoa( const int &i ) - { + + inline std::string itoa(const int& i) { std::stringstream Str; Str << i; return Str.str(); } - - inline int atoi( const std::string&s ) - { + + inline int atoi(const std::string& s) { int i; std::istringstream Str(s); Str >> i; return i; } - - // lexical cast. - template class lexical_cast - { - _From * from; + + template + class lexical_cast { + _From* from; + public: - lexical_cast<_To, _From>( _From From ) - { - this->from = & From; + lexical_cast<_To, _From>(_From From) { + this->from = &From; } - - operator _To() - { - throw( "Bad lexical cast: " ); + + operator _To() { + throw("Bad lexical cast: "); } }; - - inline - std::size_t length( std::string _String){ + + std::size_t length(std::string _String) { std::size_t length = 0; - //while (*s) - for(auto Char:_String) - length += (Char++ & 0xc0) != 0x80; + bool inEscapeCode = false; + for (auto Char : _String) { + if (inEscapeCode) { + if (Char == 'm') { + inEscapeCode = false; + } + } else { + if (Char == '\033') { + inEscapeCode = true; + } else { + length += 1; + } + } + } return length; } - - inline - std::string fill(std::string _Str, std::size_t _Size){ - - if( length(_Str) < _Size ){ + + std::string fill(std::string _Str, std::size_t _Size) { + if (length(_Str) < _Size) { std::size_t Difference = _Size - length(_Str); std::stringstream _Out; _Out << _Str; - for(int i=0; i< Difference; i++){ + for (int i = 0; i < Difference; i++) { _Out << " "; } return _Out.str(); } - return _Str; } - + } /* ascii */ #endif +