#pragma once #ifndef _NB_ANSI_TERM #define _NB_ANSI_TERM #include #include #include /* ----------- TECH DEBT ------------ Idk wtf to do here. This was originally to allow me to print to terminal easily, but it's becoming too much of an investment. For the time being, drop it. */ namespace nb { template struct SmartText { using Type = ST; using ValType = U; static constexpr bool HasChild = Type::HasChild; SmartText() = default; }; template struct StyleFormatter : SmartText, U> { using Base = SmartText, U>; using typename Base::ValType; static constexpr bool HasChild = true; StyleFormatter(const std::string& _fmt, const ValType& _val, const std::string& _closing) : fmt{_fmt}, val{_val}, closing{_closing} {} std::string fmt; ValType val; std::string closing; }; template struct StyleFormatter : SmartText, void>{ using Base = SmartText, void>; using Base::ValType; static constexpr bool HasChild = false; StyleFormatter(const std::string& _fmt) : fmt{_fmt} {} std::string fmt; }; template struct ANSITextColor; template struct ANSITextColor : StyleFormatter, U> { using Base = StyleFormatter; using typename Base::ValType; using Base::HasChild; template ::type> ANSITextColor(const U& _val) : Base{"\x1b[39m", _val, "\x1b[39m"} {} template > ANSITextColor() : Base{"\x1b[92m"} {} }; template <> struct ANSITextColor : StyleFormatter, std::string> { using Base = StyleFormatter, std::string>; static constexpr bool HasChild = Base::HasChild; template ANSITextColor(char const(&_val) [N]) : Base{"\x1b[92m", _val, "\x1b[39m"} {} ANSITextColor(const char* _val) : Base{"\x1b[92m", _val, "\x1b[39m"} {} ANSITextColor(const std::string& _val) : Base{"\x1b[92m", _val, "\x1b[39m"} {} }; } // namespace nb template std::ostream& operator<<(std::ostream& stream, const nb::StyleFormatter& msg) { if (&stream == &std::cout) { stream << msg.fmt; if (msg.HasChild) { stream << msg.val << msg.closing; } } else { if (msg.HasChild) { stream << msg.val; } } stream << std::flush; return stream; } /* struct CellBase { uint8_t width; uint8_t height; }; template struct Cell : SmartText, T> { using Base = SmartText, T>; using typename Base::ValType; using Base::HasChild; Cell(const ValType& _val, const uint8_t& w, const uint8_t& h=1) : val(_val), width(w), height(h) {} ValType val; uint8_t width; uint8_t height; }; template <> struct Cell : SmartText, std::string> { using Base = SmartText, std::string>; using typename Base::ValType; using Base::HasChild; template Cell( const(&_val) [N], const uint8_t& w, const uint8_t& h=0) : Cell(std::string(_val), w, h) {} Cell(char* _val, const uint8_t& w, const uint8_t& h=0) : Cell(std::string(_val), w, h) {} Cell(const ValType& _val, const uint8_t& w, const uint8_t& h=0) : val(_val), width(w) { unsigned int strsize = _val.size(); height = strsize / width; height += (strsize % width) ? 1 : 0; } ValType val; uint8_t width; uint8_t height; }; template std::ostream& operator<<(std::ostream& stream, const Cell& cll) { if (&stream == &std::cout) { stream << "\x1b[s" << cll.val << "\x1b[u\x1b[" << 1+cll.width << "C\x1b[" << 1+cll.height; } return stream; } template void ChangeCellHeight(int i, Cell& cll, const unsigned int& h) { if (h < cll.height) { cll.height=h; } } template void GetTallestCell(int i, Cell& cll, unsigned int& h) { if (cll.height > h) { h = cll.height; } } template struct TableRow { using RowCells = std::tuple...>; using CellWidths = std::array; using DelimiterArray = std::array; TableRow(CellWidths&& widths_, DelimiterArray&& delims_, const Pack&... vals_) : widths(widths_), delimiters(delims_), topBorder("") { nb::ForEach(_cells, GetTallestCell, _height); } static constexpr int num_columns = sizeof...(Pack); int height() const { return height; } inline int height(const unsigned int newh) { nb::ForEach(_cells, ChangeCellHeight, newh); return (_height=newh); } const CellWidths widths; const DelimiterArray delimiters; const std::string topBorder; const std::string bottomBorder; protected: RowCells _cells; int _height; }; template std::ostream& operator<<(std::ostream& stream, const TableRow& row) { } template class Table { public: Table(const Pack&... _vals) : row(std::array(10), std::array(""), _vals...) {} private: TableRow row; }; } // namespace nb #ifdef _NB_TARGET_WINDOWS template std::ostream& operator<<(std::ostream& stream, const nb::TableRow& row) { using PosType = decltype(stream.tellp()); constexpr int num_cells = sizeof...(Types); int col_num = 0; int col_start = 0; return stream; } #endif // _NB_TARGET_WINDOWS */ #endif // _NB_ANSI_TERM