diff --git a/CMakeLists.txt b/CMakeLists.txt index 2730c76..30d7fd3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.0) -project(libfort VERSION 0.2.3) +project(libfort VERSION 0.3.0) string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1.\\2" libfort_SOVERSION @@ -220,8 +220,10 @@ if(FORT_ENABLE_ASTYLE) --min-conditional-indent=0 --indent=spaces=4 ${CMAKE_SOURCE_DIR}/lib/*.h + ${CMAKE_SOURCE_DIR}/lib/*.hpp ${CMAKE_SOURCE_DIR}/lib/*.c ${CMAKE_SOURCE_DIR}/src/*.h + ${CMAKE_SOURCE_DIR}/src/*.hpp ${CMAKE_SOURCE_DIR}/src/*.c ${CMAKE_SOURCE_DIR}/tests/*.c ${CMAKE_SOURCE_DIR}/tests/*.h diff --git a/ChangeLog.md b/ChangeLog.md index 82d8554..59a6fdd 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,4 +1,8 @@ -## v0.2.3 +## v0.3.0 + +### API + +- Changes in C++ API (introduced classes `char_table` and `utf8-table` instead of `table`). ### Internal diff --git a/examples/1-simple_table.cpp b/examples/1-simple_table.cpp index 62afbeb..6cd3cd9 100644 --- a/examples/1-simple_table.cpp +++ b/examples/1-simple_table.cpp @@ -5,7 +5,7 @@ int main() { - fort::table table; + fort::char_table table; table << fort::header << "N" << "Driver" << "Time" << "Avg Speed" << fort::endr << "1" << "Ricciardo" << "1:25.945" << "47.362" << fort::endr diff --git a/examples/2-custom_table.cpp b/examples/2-custom_table.cpp index aaa318c..b2af8f1 100644 --- a/examples/2-custom_table.cpp +++ b/examples/2-custom_table.cpp @@ -4,7 +4,7 @@ int main() { - fort::table table; + fort::char_table table; /* Set table border style */ table.set_border_style(FT_NICE_STYLE); diff --git a/examples/3-complex_layout.cpp b/examples/3-complex_layout.cpp index 962b2b8..b9975b4 100644 --- a/examples/3-complex_layout.cpp +++ b/examples/3-complex_layout.cpp @@ -5,7 +5,7 @@ int main() { - fort::table table; + fort::char_table table; /* Set table border style */ table.set_border_style(FT_DOUBLE2_STYLE); diff --git a/examples/4-fill_table.cpp b/examples/4-fill_table.cpp index 4029288..645a26d 100644 --- a/examples/4-fill_table.cpp +++ b/examples/4-fill_table.cpp @@ -5,7 +5,7 @@ int main(void) { - fort::table table; + fort::char_table table; table << fort::header; /* Fill each cell with operator[] */ table [0][0] = "N"; diff --git a/examples/9-non_ascii_table.c b/examples/9-non_ascii_table.c index 67ab025..55a6885 100644 --- a/examples/9-non_ascii_table.c +++ b/examples/9-non_ascii_table.c @@ -8,34 +8,50 @@ int main(void) { +#if defined(FT_HAVE_UTF8) + /* Example of utf8 table */ + { + ft_table_t *table = ft_create_table(); + ft_set_border_style(table, FT_NICE_STYLE); + + ft_set_cell_prop(table, FT_ANY_ROW, 0, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_CENTER); + ft_set_cell_prop(table, FT_ANY_ROW, 1, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_LEFT); + + ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER); + ft_u8write_ln(table, "Ранг", "Название", "Год", "Рейтинг"); + + ft_u8write_ln(table, "1", "Побег из Шоушенка", "1994", "9.5"); + ft_u8write_ln(table, "2", "12 разгневанных мужчин", "1957", "8.8"); + ft_u8write_ln(table, "3", "Космическая одиссея 2001 года", "1968", "8.5"); + ft_u8write_ln(table, "4", "Бегущий по лезвию", "1982", "8.1"); + const char *table_str = (const char *)ft_to_u8string(table); + printf("%s\n", table_str); + ft_destroy_table(table); + } +#endif + + /* Example of wchar table */ #if defined(FT_HAVE_WCHAR) && !defined(FT_MICROSOFT_COMPILER) - setlocale(LC_CTYPE, ""); + { + setlocale(LC_CTYPE, ""); - ft_set_default_border_style(FT_BASIC_STYLE); + ft_set_default_border_style(FT_BASIC_STYLE); - ft_table_t *table = ft_create_table(); - ft_set_cell_prop(table, FT_ANY_ROW, 0, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_CENTER); - ft_set_cell_prop(table, FT_ANY_ROW, 1, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_LEFT); + ft_table_t *table = ft_create_table(); + ft_set_cell_prop(table, FT_ANY_ROW, 0, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_CENTER); + ft_set_cell_prop(table, FT_ANY_ROW, 1, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_LEFT); - ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER); - ft_wwrite_ln(table, L"Ранг", L"Название", L"Год", L"Рейтинг"); + ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER); + ft_wwrite_ln(table, L"Ранг", L"Название", L"Год", L"Рейтинг"); - ft_wwrite_ln(table, L"1", L"Побег из Шоушенка", L"1994", L"9.5"); - ft_wwrite_ln(table, L"2", L"12 разгневанных мужчин", L"1957", L"8.8"); - ft_wwrite_ln(table, L"3", L"Космическая одиссея 2001 года", L"1968", L"8.5"); - ft_wwrite_ln(table, L"4", L"Бегущий по лезвию", L"1982", L"8.1"); - - /* Ранг | Название | Год | Рейтинг */ - /*FT_NWWRITE_LN(table, L"\x420\x430\x43d\x433", L"\x41d\x430\x437\x432\x430\x43d\x438\x435", L"\x413\x43e\x434", L"\x420\x435\x439\x442\x438\x43d\x433"); */ - - /*FT_NWWRITE_LN(table, L"1", L"\x41f\x43e\x431\x435\x433 \x438\x437 \x428\x43e\x443\x448\x435\x43d\x43a\x430", L"1994", L"9.5");*/ /* Побег из Шоушенка */ - /*FT_NWWRITE_LN(table, L"2", L"12 \x440\x430\x437\x433\x43d\x435\x432\x430\x43d\x43d\x44b\x445 \x43c\x443\x436\x447\x438\x43d", L"1957", L"8.8");*/ /* 12 разгневанных мужчин */ - /*FT_NWWRITE_LN(table, L"3", L"\x41a\x43e\x441\x43c\x438\x447\x435\x441\x43a\x430\x44f \x43e\x434\x438\x441\x441\x435\x44f 2001 \x433\x43e\x434\x430", L"1968", L"8.5");*/ /* Космическая одиссея 2001 года */ - /*FT_NWWRITE_LN(table, L"4", L"\x411\x435\x433\x443\x449\x438\x439 \x43f\x43e \x43b\x435\x437\x432\x438\x44e", L"1982", L"8.1");*/ /* Бегущий по лезвию */ - - const wchar_t* table_wstr = ft_to_wstring(table); - fwprintf(stderr, L"%ls\n ", table_wstr); - ft_destroy_table(table); + ft_wwrite_ln(table, L"1", L"Побег из Шоушенка", L"1994", L"9.5"); + ft_wwrite_ln(table, L"2", L"12 разгневанных мужчин", L"1957", L"8.8"); + ft_wwrite_ln(table, L"3", L"Космическая одиссея 2001 года", L"1968", L"8.5"); + ft_wwrite_ln(table, L"4", L"Бегущий по лезвию", L"1982", L"8.1"); + const wchar_t* table_wstr = ft_to_wstring(table); + fwprintf(stderr, L"%ls\n", table_wstr); + ft_destroy_table(table); + } #endif return 0; diff --git a/examples/9-non_ascii_table.cpp b/examples/9-non_ascii_table.cpp new file mode 100644 index 0000000..cbdf636 --- /dev/null +++ b/examples/9-non_ascii_table.cpp @@ -0,0 +1,30 @@ +#include + + +#include "fort.hpp" + + +int main(void) +{ +#if defined(FT_HAVE_UTF8) + /* Example of utf8 table */ + { + fort::utf8_table table; + table.set_border_style(FT_NICE_STYLE); + + table.column(0).set_cell_text_align(fort::text_align::center); + table.column(1).set_cell_text_align(fort::text_align::center); + + table << fort::header + << "Ранг" << "Название" << "Год" << "Рейтинг" << fort::endr + << "1" << "Побег из Шоушенка" << "1994" << "9.5"<< fort::endr + << "2" << "12 разгневанных мужчин" << "1957" << "8.8" << fort::endr + << "3" << "Космическая одиссея 2001 года" << "1968" << "8.5" << fort::endr + << "4" << "Бегущий по лезвию" << "1982" << "8.1" << fort::endr; + + std::cout << table.to_string() << std::endl; + } +#endif + + return 0; +} diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 16568df..f004724 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -67,6 +67,12 @@ add_executable(${PROJECT_NAME}_fill_table_cpp target_link_libraries(${PROJECT_NAME}_fill_table_cpp fort) +add_executable(${PROJECT_NAME}_non_ascii_table_cpp + 9-non_ascii_table.cpp) +target_link_libraries(${PROJECT_NAME}_non_ascii_table_cpp + fort) + + add_executable(${PROJECT_NAME}_ex_cpp main.cpp) target_link_libraries(${PROJECT_NAME}_ex_cpp @@ -88,6 +94,7 @@ set(${PROJECT_NAME}_examples ${PROJECT_NAME}_custom_table_cpp ${PROJECT_NAME}_complex_layout_cpp ${PROJECT_NAME}_fill_table_cpp + ${PROJECT_NAME}_non_ascii_table_cpp PARENT_SCOPE) if(DEFINED FORT_LINK_LIBRARIES) diff --git a/examples/main.cpp b/examples/main.cpp index 3a58492..04ae0a5 100644 --- a/examples/main.cpp +++ b/examples/main.cpp @@ -6,7 +6,7 @@ int main() { { - fort::table table; + fort::char_table table; // Fill table with data table << fort::header << "Rank" << "Title" << "Year" << "Rating" << fort::endr @@ -27,7 +27,7 @@ int main() { - fort::table table; + fort::char_table table; // Fill table with data table << fort::header; table.write_ln("Rank", "Title", "Year", "Rating"); @@ -49,7 +49,7 @@ int main() } { - fort::table table; + fort::char_table table; // Fill table with data table << fort::header << "Rank" << "Title" << "Year" << "Rating" << fort::endr @@ -66,7 +66,7 @@ int main() } { - fort::table table; + fort::char_table table; /* Set table border style */ table.set_border_style(FT_BASIC_STYLE); diff --git a/lib/fort.h b/lib/fort.h index 2190080..ca3ac6d 100644 --- a/lib/fort.h +++ b/lib/fort.h @@ -45,9 +45,9 @@ SOFTWARE. *****************************************************************************/ #define LIBFORT_MAJOR_VERSION 0 -#define LIBFORT_MINOR_VERSION 2 -#define LIBFORT_REVISION 3 -#define LIBFORT_VERSION_STR "0.2.3" +#define LIBFORT_MINOR_VERSION 3 +#define LIBFORT_REVISION 0 +#define LIBFORT_VERSION_STR "0.3.0" /***************************************************************************** diff --git a/lib/fort.hpp b/lib/fort.hpp index c3f8ddd..c776a99 100644 --- a/lib/fort.hpp +++ b/lib/fort.hpp @@ -97,18 +97,28 @@ enum class text_style { hidden = FT_TSTYLE_HIDDEN }; + +enum class table_type { + character, +#ifdef FT_HAVE_UTF8 + utf8 +#endif /* FT_HAVE_UTF8 */ +}; + /** * Table manipulator. * * Table manipulators can be used to change current cell and change appearance * of cells. */ -class table_manipulator { +class table_manipulator +{ public: explicit table_manipulator(int i) - :value(i) + : value(i) { } + template friend class table; private: int value; @@ -136,11 +146,12 @@ const table_manipulator separator(2); * which user can specify properties. */ template -class property_owner { +class property_owner +{ public: property_owner(std::size_t row_idx, std::size_t coll_idx, table *tbl, bool def = false) - :ps_row_idx_(row_idx), ps_coll_idx_(coll_idx), + : ps_row_idx_(row_idx), ps_coll_idx_(coll_idx), ps_table_(tbl), set_default_properties_(def) {} /** @@ -343,19 +354,31 @@ protected: } }; + /** * Formatted table. * - * Table class is a C++ wrapper around struct ft_table. + * Table template class is a C++ wrapper around struct {@link ft_table}. + * Template parameter is {@link table_type}. Useful instantiations of table + * template class are {@link char_table} and {@link utf8_table}. */ -class table: public property_owner { +template +class table: public property_owner> +{ + /** + * Utility types. + */ + using table_t = table; + using property_owner_t = property_owner; + public: /** * Default constructor. */ table() - :property_owner(FT_ANY_ROW, FT_ANY_COLUMN, this), table_(ft_create_table()) + : property_owner_t(FT_ANY_ROW, FT_ANY_COLUMN, this), + table_(ft_create_table()) { if (table_ == NULL) @@ -373,8 +396,8 @@ public: /** * Copy contstructor. */ - table(const table& tbl) - :property_owner(FT_ANY_ROW, FT_ANY_COLUMN, this), table_(NULL) + table(const table &tbl) + : property_owner_t(FT_ANY_ROW, FT_ANY_COLUMN, this), table_(NULL) { if (tbl.table_) { ft_table_t *table_copy = ft_copy_table(tbl.table_); @@ -392,8 +415,8 @@ public: /** * Move contstructor. */ - table(table&& tbl) - :property_owner(FT_ANY_ROW, FT_ANY_COLUMN, this), table_(tbl.table_) + table(table &&tbl) + : property_owner_t(FT_ANY_ROW, FT_ANY_COLUMN, this), table_(tbl.table_) { if (tbl.stream_.tellp() >= 0) { stream_ << tbl.stream_.str(); @@ -405,7 +428,7 @@ public: /** * Copy assignment operator. */ - table& operator=(const table& tbl) + table &operator=(const table &tbl) { if (&tbl == this) return *this; @@ -428,7 +451,7 @@ public: /** * Move assignment operator. */ - table& operator=(table&& tbl) + table &operator=(table &&tbl) { if (&tbl == this) return *this; @@ -455,7 +478,7 @@ public: */ std::string to_string() const { - const char *str = ft_to_string(table_); + const char *str = c_str(); if (str == NULL) throw std::runtime_error("Libfort runtime error"); return str; @@ -478,7 +501,13 @@ public: */ const char *c_str() const { +#ifdef FT_HAVE_UTF8 + return (TT == table_type::character) + ? ft_to_string(table_) + : (const char *)ft_to_u8string(table_); +#else return ft_to_string(table_); +#endif } /** @@ -497,7 +526,16 @@ public: { stream_ << arg; if (stream_.tellp() >= 0) { +#ifdef FT_HAVE_UTF8 + if (TT == table_type::character) { + ft_nwrite(table_, 1, stream_.str().c_str()); + } else { + ft_u8nwrite(table_, 1, (const void *)stream_.str().c_str()); + } +#else ft_nwrite(table_, 1, stream_.str().c_str()); +#endif + stream_.str(std::string()); } return *this; @@ -527,7 +565,15 @@ public: */ bool write(const char *str) { +#ifdef FT_HAVE_UTF8 + if (TT == table_type::character) { + return FT_IS_SUCCESS(ft_write(table_, str)); + } else { + return FT_IS_SUCCESS(ft_u8write(table_, (const void *)str)); + } +#else return FT_IS_SUCCESS(ft_write(table_, str)); +#endif } /** @@ -544,7 +590,15 @@ public: */ bool write_ln(const char *str) { +#ifdef FT_HAVE_UTF8 + if (TT == table_type::character) { + return FT_IS_SUCCESS(ft_write_ln(table_, str)); + } else { + return FT_IS_SUCCESS(ft_u8write_ln(table_, str)); + } +#else return FT_IS_SUCCESS(ft_write_ln(table_, str)); +#endif } /** @@ -853,20 +907,24 @@ public: /** * Table cell. */ - class table_cell: public property_owner
+ class table_cell: public property_owner_t { + using property_owner_t::ps_coll_idx_; + using property_owner_t::ps_row_idx_; + using property_owner_t::ps_table_; + using property_owner_t::set_default_properties_; public: table_cell(std::size_t row_idx, std::size_t coll_idx, table &tbl) - :property_owner(row_idx, coll_idx, &tbl) {} + : property_owner_t(row_idx, coll_idx, &tbl) {} - table_cell& operator=(const char *str) + table_cell &operator=(const char *str) { ft_set_cur_cell(ps_table_->table_, ps_row_idx_, ps_coll_idx_); ps_table_->write(str); return *this; } - table_cell& operator=(const std::string &str) + table_cell &operator=(const std::string &str) { return operator=(str.c_str()); } @@ -892,14 +950,16 @@ public: /** * Table row. */ - class table_row: public property_owner
+ class table_row: public property_owner_t { + using property_owner_t::ps_row_idx_; + using property_owner_t::ps_table_; public: table_row(std::size_t row_idx, table &tbl) - :property_owner(row_idx, FT_ANY_COLUMN, &tbl) {} + : property_owner_t(row_idx, FT_ANY_COLUMN, &tbl) {} class table_cell - operator[](std::size_t coll_idx) + operator[](std::size_t coll_idx) { return table_cell(ps_row_idx_, coll_idx, *ps_table_); } @@ -908,22 +968,22 @@ public: /** * Table column. */ - class table_column: public property_owner
+ class table_column: public property_owner_t { public: table_column(std::size_t col_idx, table &tbl) - :property_owner(FT_ANY_ROW, col_idx, &tbl) {} + : property_owner_t(FT_ANY_ROW, col_idx, &tbl) {} }; - class default_properties: public property_owner
+ class default_properties: public property_owner_t { public: default_properties(table *tbl) - :property_owner(FT_ANY_ROW, FT_ANY_COLUMN, tbl, true) {} + : property_owner_t(FT_ANY_ROW, FT_ANY_COLUMN, tbl, true) {} }; class table_row - operator[](std::size_t row_idx) + operator[](std::size_t row_idx) { return table_row(row_idx, *this); } @@ -940,7 +1000,7 @@ public: * table_cell object. */ class table_cell - cell(std::size_t row_idx, std::size_t col_idx) + cell(std::size_t row_idx, std::size_t col_idx) { return (*this)[row_idx][col_idx]; } @@ -976,7 +1036,7 @@ public: * Current cell. */ class table_cell - cur_cell() + cur_cell() { return cell(cur_row(), cur_col()); } @@ -990,7 +1050,7 @@ public: * table_row object. */ class table_row - row(std::size_t row_idx) + row(std::size_t row_idx) { return table_row(row_idx, *this); } @@ -1004,18 +1064,33 @@ public: * table_column object. */ class table_column - column(std::size_t col_idx) + column(std::size_t col_idx) { return table_column(col_idx, *this); } static class default_properties - default_props() + default_props() { return default_properties(NULL); } }; +/** + * Formatted table containing common char content. + * + * Content of the table is treated as a string where each byte represesents a + * character. Should work for ascii characters. In case of usage of different + * international symbols it is recommended to use {@link utf8_table}. + */ +using char_table = table; + +#ifdef FT_HAVE_UTF8 +/** + * Formatted table containing utf-8 content. + */ +using utf8_table = table; +#endif /** * Set default border style for all new formatted tables. @@ -1032,6 +1107,6 @@ inline bool set_default_border_style(struct ft_border_style *style) } -} +} // namespace fort #endif // LIBFORT_HPP diff --git a/src/fort.h b/src/fort.h index 2190080..ca3ac6d 100644 --- a/src/fort.h +++ b/src/fort.h @@ -45,9 +45,9 @@ SOFTWARE. *****************************************************************************/ #define LIBFORT_MAJOR_VERSION 0 -#define LIBFORT_MINOR_VERSION 2 -#define LIBFORT_REVISION 3 -#define LIBFORT_VERSION_STR "0.2.3" +#define LIBFORT_MINOR_VERSION 3 +#define LIBFORT_REVISION 0 +#define LIBFORT_VERSION_STR "0.3.0" /***************************************************************************** diff --git a/src/fort.hpp b/src/fort.hpp index c3f8ddd..c776a99 100644 --- a/src/fort.hpp +++ b/src/fort.hpp @@ -97,18 +97,28 @@ enum class text_style { hidden = FT_TSTYLE_HIDDEN }; + +enum class table_type { + character, +#ifdef FT_HAVE_UTF8 + utf8 +#endif /* FT_HAVE_UTF8 */ +}; + /** * Table manipulator. * * Table manipulators can be used to change current cell and change appearance * of cells. */ -class table_manipulator { +class table_manipulator +{ public: explicit table_manipulator(int i) - :value(i) + : value(i) { } + template friend class table; private: int value; @@ -136,11 +146,12 @@ const table_manipulator separator(2); * which user can specify properties. */ template -class property_owner { +class property_owner +{ public: property_owner(std::size_t row_idx, std::size_t coll_idx, table *tbl, bool def = false) - :ps_row_idx_(row_idx), ps_coll_idx_(coll_idx), + : ps_row_idx_(row_idx), ps_coll_idx_(coll_idx), ps_table_(tbl), set_default_properties_(def) {} /** @@ -343,19 +354,31 @@ protected: } }; + /** * Formatted table. * - * Table class is a C++ wrapper around struct ft_table. + * Table template class is a C++ wrapper around struct {@link ft_table}. + * Template parameter is {@link table_type}. Useful instantiations of table + * template class are {@link char_table} and {@link utf8_table}. */ -class table: public property_owner
{ +template +class table: public property_owner> +{ + /** + * Utility types. + */ + using table_t = table; + using property_owner_t = property_owner; + public: /** * Default constructor. */ table() - :property_owner(FT_ANY_ROW, FT_ANY_COLUMN, this), table_(ft_create_table()) + : property_owner_t(FT_ANY_ROW, FT_ANY_COLUMN, this), + table_(ft_create_table()) { if (table_ == NULL) @@ -373,8 +396,8 @@ public: /** * Copy contstructor. */ - table(const table& tbl) - :property_owner(FT_ANY_ROW, FT_ANY_COLUMN, this), table_(NULL) + table(const table &tbl) + : property_owner_t(FT_ANY_ROW, FT_ANY_COLUMN, this), table_(NULL) { if (tbl.table_) { ft_table_t *table_copy = ft_copy_table(tbl.table_); @@ -392,8 +415,8 @@ public: /** * Move contstructor. */ - table(table&& tbl) - :property_owner(FT_ANY_ROW, FT_ANY_COLUMN, this), table_(tbl.table_) + table(table &&tbl) + : property_owner_t(FT_ANY_ROW, FT_ANY_COLUMN, this), table_(tbl.table_) { if (tbl.stream_.tellp() >= 0) { stream_ << tbl.stream_.str(); @@ -405,7 +428,7 @@ public: /** * Copy assignment operator. */ - table& operator=(const table& tbl) + table &operator=(const table &tbl) { if (&tbl == this) return *this; @@ -428,7 +451,7 @@ public: /** * Move assignment operator. */ - table& operator=(table&& tbl) + table &operator=(table &&tbl) { if (&tbl == this) return *this; @@ -455,7 +478,7 @@ public: */ std::string to_string() const { - const char *str = ft_to_string(table_); + const char *str = c_str(); if (str == NULL) throw std::runtime_error("Libfort runtime error"); return str; @@ -478,7 +501,13 @@ public: */ const char *c_str() const { +#ifdef FT_HAVE_UTF8 + return (TT == table_type::character) + ? ft_to_string(table_) + : (const char *)ft_to_u8string(table_); +#else return ft_to_string(table_); +#endif } /** @@ -497,7 +526,16 @@ public: { stream_ << arg; if (stream_.tellp() >= 0) { +#ifdef FT_HAVE_UTF8 + if (TT == table_type::character) { + ft_nwrite(table_, 1, stream_.str().c_str()); + } else { + ft_u8nwrite(table_, 1, (const void *)stream_.str().c_str()); + } +#else ft_nwrite(table_, 1, stream_.str().c_str()); +#endif + stream_.str(std::string()); } return *this; @@ -527,7 +565,15 @@ public: */ bool write(const char *str) { +#ifdef FT_HAVE_UTF8 + if (TT == table_type::character) { + return FT_IS_SUCCESS(ft_write(table_, str)); + } else { + return FT_IS_SUCCESS(ft_u8write(table_, (const void *)str)); + } +#else return FT_IS_SUCCESS(ft_write(table_, str)); +#endif } /** @@ -544,7 +590,15 @@ public: */ bool write_ln(const char *str) { +#ifdef FT_HAVE_UTF8 + if (TT == table_type::character) { + return FT_IS_SUCCESS(ft_write_ln(table_, str)); + } else { + return FT_IS_SUCCESS(ft_u8write_ln(table_, str)); + } +#else return FT_IS_SUCCESS(ft_write_ln(table_, str)); +#endif } /** @@ -853,20 +907,24 @@ public: /** * Table cell. */ - class table_cell: public property_owner
+ class table_cell: public property_owner_t { + using property_owner_t::ps_coll_idx_; + using property_owner_t::ps_row_idx_; + using property_owner_t::ps_table_; + using property_owner_t::set_default_properties_; public: table_cell(std::size_t row_idx, std::size_t coll_idx, table &tbl) - :property_owner(row_idx, coll_idx, &tbl) {} + : property_owner_t(row_idx, coll_idx, &tbl) {} - table_cell& operator=(const char *str) + table_cell &operator=(const char *str) { ft_set_cur_cell(ps_table_->table_, ps_row_idx_, ps_coll_idx_); ps_table_->write(str); return *this; } - table_cell& operator=(const std::string &str) + table_cell &operator=(const std::string &str) { return operator=(str.c_str()); } @@ -892,14 +950,16 @@ public: /** * Table row. */ - class table_row: public property_owner
+ class table_row: public property_owner_t { + using property_owner_t::ps_row_idx_; + using property_owner_t::ps_table_; public: table_row(std::size_t row_idx, table &tbl) - :property_owner(row_idx, FT_ANY_COLUMN, &tbl) {} + : property_owner_t(row_idx, FT_ANY_COLUMN, &tbl) {} class table_cell - operator[](std::size_t coll_idx) + operator[](std::size_t coll_idx) { return table_cell(ps_row_idx_, coll_idx, *ps_table_); } @@ -908,22 +968,22 @@ public: /** * Table column. */ - class table_column: public property_owner
+ class table_column: public property_owner_t { public: table_column(std::size_t col_idx, table &tbl) - :property_owner(FT_ANY_ROW, col_idx, &tbl) {} + : property_owner_t(FT_ANY_ROW, col_idx, &tbl) {} }; - class default_properties: public property_owner
+ class default_properties: public property_owner_t { public: default_properties(table *tbl) - :property_owner(FT_ANY_ROW, FT_ANY_COLUMN, tbl, true) {} + : property_owner_t(FT_ANY_ROW, FT_ANY_COLUMN, tbl, true) {} }; class table_row - operator[](std::size_t row_idx) + operator[](std::size_t row_idx) { return table_row(row_idx, *this); } @@ -940,7 +1000,7 @@ public: * table_cell object. */ class table_cell - cell(std::size_t row_idx, std::size_t col_idx) + cell(std::size_t row_idx, std::size_t col_idx) { return (*this)[row_idx][col_idx]; } @@ -976,7 +1036,7 @@ public: * Current cell. */ class table_cell - cur_cell() + cur_cell() { return cell(cur_row(), cur_col()); } @@ -990,7 +1050,7 @@ public: * table_row object. */ class table_row - row(std::size_t row_idx) + row(std::size_t row_idx) { return table_row(row_idx, *this); } @@ -1004,18 +1064,33 @@ public: * table_column object. */ class table_column - column(std::size_t col_idx) + column(std::size_t col_idx) { return table_column(col_idx, *this); } static class default_properties - default_props() + default_props() { return default_properties(NULL); } }; +/** + * Formatted table containing common char content. + * + * Content of the table is treated as a string where each byte represesents a + * character. Should work for ascii characters. In case of usage of different + * international symbols it is recommended to use {@link utf8_table}. + */ +using char_table = table; + +#ifdef FT_HAVE_UTF8 +/** + * Formatted table containing utf-8 content. + */ +using utf8_table = table; +#endif /** * Set default border style for all new formatted tables. @@ -1032,6 +1107,6 @@ inline bool set_default_border_style(struct ft_border_style *style) } -} +} // namespace fort #endif // LIBFORT_HPP diff --git a/tests/bb_tests_cpp/test_table_basic.cpp b/tests/bb_tests_cpp/test_table_basic.cpp index 44e5c05..f8f04e0 100644 --- a/tests/bb_tests_cpp/test_table_basic.cpp +++ b/tests/bb_tests_cpp/test_table_basic.cpp @@ -2,10 +2,11 @@ #include "fort.hpp" #include "test_utils.hpp" + void test_cpp_bug_fixes(void) { SCENARIO("Issue 11 - https://github.com/seleznevae/libfort/issues/11") { - fort::table table; + fort::char_table table; table << fort::header << "1" << "2" << fort::endr << "3" << "4" << fort::endr; @@ -30,7 +31,7 @@ void test_cpp_bug_fixes(void) void test_cpp_table_basic(void) { WHEN("All columns are equal and not empty.") { - fort::table table; + fort::char_table table; assert_true(set_cpp_test_props_for_table(&table)); table << fort::header @@ -57,7 +58,7 @@ void test_cpp_table_basic(void) } WHEN("Checking basic constructors and assignmets.") { - fort::table table; + fort::char_table table; assert_true(set_cpp_test_props_for_table(&table)); table << fort::header @@ -65,12 +66,12 @@ void test_cpp_table_basic(void) << "3" << "c" << "234" << "3.140000" << fort::endr << "3" << "c" << "234" << "3.140000" << fort::endr; - fort::table table2(std::move(table)); - fort::table table3; + fort::char_table table2(std::move(table)); + fort::char_table table3; table3 = std::move(table2); - fort::table table4(table3); - fort::table table5; + fort::char_table table4(table3); + fort::char_table table5; table5 = table4; std::string table_str = table5.to_string(); @@ -92,7 +93,7 @@ void test_cpp_table_basic(void) } WHEN("All columns are not equal and not empty") { - fort::table table; + fort::char_table table; assert_true(set_cpp_test_props_for_table(&table)); table << fort::header @@ -119,7 +120,7 @@ void test_cpp_table_basic(void) } WHEN("All columns are not equal and some cells are empty") { - fort::table table; + fort::char_table table; assert_true(set_cpp_test_props_for_table(&table)); table << fort::header @@ -146,7 +147,7 @@ void test_cpp_table_basic(void) } WHEN("All cells are empty") { - fort::table table; + fort::char_table table; assert_true(set_cpp_test_props_for_table(&table)); table << fort::header @@ -177,7 +178,7 @@ void test_cpp_table_basic(void) void test_cpp_table_write(void) { SCENARIO("Test write functions") { - fort::table table; + fort::char_table table; assert_true(set_cpp_test_props_for_table(&table)); table << fort::header; assert_true(table.write("3")); @@ -219,7 +220,7 @@ void test_cpp_table_write(void) } SCENARIO("Test n write functions") { - fort::table table; + fort::char_table table; assert_true(set_cpp_test_props_for_table(&table)); table << fort::header; assert_true(table.write("3", "c", "234", "3.140000")); @@ -251,7 +252,7 @@ void test_cpp_table_write(void) } SCENARIO("Test range_write functions") { - fort::table table; + fort::char_table table; assert_true(set_cpp_test_props_for_table(&table)); table << fort::header; @@ -291,7 +292,7 @@ void test_cpp_table_write(void) void test_cpp_table_changing_cell(void) { WHEN("All columns are equal and not empty") { - fort::table table; + fort::char_table table; assert_true(set_cpp_test_props_for_table(&table)); table << fort::header diff --git a/tests/bb_tests_cpp/test_table_properties.cpp b/tests/bb_tests_cpp/test_table_properties.cpp index 6dffe89..76a95ad 100644 --- a/tests/bb_tests_cpp/test_table_properties.cpp +++ b/tests/bb_tests_cpp/test_table_properties.cpp @@ -5,7 +5,7 @@ void test_cpp_table_tbl_properties(void) { - fort::table table; + fort::char_table table; WHEN("Test setting entire table properties") { set_test_properties_as_default(); @@ -66,7 +66,7 @@ void test_cpp_table_cell_properties(void) WHEN("Setting property for one cell") { set_test_properties_as_default(); - fort::table table = create_cpp_test_int_table(false); + fort::char_table table = create_cpp_test_int_table(false); table[1][1].set_cell_top_padding(2); std::string table_str = table.to_string(); @@ -91,7 +91,7 @@ void test_cpp_table_cell_properties(void) WHEN("Setting property for one cell(2)") { set_test_properties_as_default(); - fort::table table = create_cpp_test_int_table(false); + fort::char_table table = create_cpp_test_int_table(false); table.cell(1, 1).set_cell_top_padding(2); std::string table_str = table.to_string(); @@ -116,7 +116,7 @@ void test_cpp_table_cell_properties(void) WHEN("Setting property for the row") { set_test_properties_as_default(); - fort::table table = create_cpp_test_int_table(false); + fort::char_table table = create_cpp_test_int_table(false); table[1].set_cell_top_padding(2); std::string table_str = table.to_string(); @@ -141,7 +141,7 @@ void test_cpp_table_cell_properties(void) WHEN("Setting property for the column") { set_test_properties_as_default(); - fort::table table = create_cpp_test_int_table(false); + fort::char_table table = create_cpp_test_int_table(false); table.column(1).set_cell_top_padding(2); std::string table_str = table.to_string(); @@ -168,7 +168,7 @@ void test_cpp_table_cell_properties(void) WHEN("Setting property for all cells in the table") { set_test_properties_as_default(); - fort::table table = create_cpp_test_int_table(false); + fort::char_table table = create_cpp_test_int_table(false); table.set_cell_top_padding(2); std::string table_str = table.to_string(); @@ -195,12 +195,12 @@ void test_cpp_table_cell_properties(void) WHEN("All paddings = 1") { set_test_properties_as_default(); - fort::table::default_props().set_cell_top_padding(2); - fort::table::default_props().set_cell_bottom_padding(3); - fort::table::default_props().set_cell_left_padding(1); - fort::table::default_props().set_cell_right_padding(0); + fort::char_table::default_props().set_cell_top_padding(2); + fort::char_table::default_props().set_cell_bottom_padding(3); + fort::char_table::default_props().set_cell_left_padding(1); + fort::char_table::default_props().set_cell_right_padding(0); - fort::table table = create_cpp_test_int_table(false); + fort::char_table table = create_cpp_test_int_table(false); std::string table_str = table.to_string(); std::string table_str_etalon = @@ -230,12 +230,12 @@ void test_cpp_table_cell_properties(void) } WHEN("Top and bottom padding = 0") { - fort::table::default_props().set_cell_top_padding(0); - fort::table::default_props().set_cell_bottom_padding(0); - fort::table::default_props().set_cell_left_padding(1); - fort::table::default_props().set_cell_right_padding(1); + fort::char_table::default_props().set_cell_top_padding(0); + fort::char_table::default_props().set_cell_bottom_padding(0); + fort::char_table::default_props().set_cell_left_padding(1); + fort::char_table::default_props().set_cell_right_padding(1); - fort::table table = create_cpp_test_int_table(false); + fort::char_table table = create_cpp_test_int_table(false); std::string table_str = table.to_string(); std::string table_str_etalon = @@ -250,12 +250,12 @@ void test_cpp_table_cell_properties(void) } WHEN("Left and right padding = 0") { - fort::table::default_props().set_cell_top_padding(1); - fort::table::default_props().set_cell_bottom_padding(1); - fort::table::default_props().set_cell_left_padding(0); - fort::table::default_props().set_cell_right_padding(0); + fort::char_table::default_props().set_cell_top_padding(1); + fort::char_table::default_props().set_cell_bottom_padding(1); + fort::char_table::default_props().set_cell_left_padding(0); + fort::char_table::default_props().set_cell_right_padding(0); - fort::table table = create_cpp_test_int_table(false); + fort::char_table table = create_cpp_test_int_table(false); std::string table_str = table.to_string(); std::string table_str_etalon = @@ -276,12 +276,12 @@ void test_cpp_table_cell_properties(void) } WHEN("All paddings = 0") { - fort::table::default_props().set_cell_top_padding(0); - fort::table::default_props().set_cell_bottom_padding(0); - fort::table::default_props().set_cell_left_padding(0); - fort::table::default_props().set_cell_right_padding(0); + fort::char_table::default_props().set_cell_top_padding(0); + fort::char_table::default_props().set_cell_bottom_padding(0); + fort::char_table::default_props().set_cell_left_padding(0); + fort::char_table::default_props().set_cell_right_padding(0); - fort::table table = create_cpp_test_int_table(false); + fort::char_table table = create_cpp_test_int_table(false); std::string table_str = table.to_string(); std::string table_str_etalon = @@ -296,13 +296,13 @@ void test_cpp_table_cell_properties(void) } WHEN("Empty string has 0 heigt") { - fort::table::default_props().set_cell_top_padding(1); - fort::table::default_props().set_cell_bottom_padding(1); - fort::table::default_props().set_cell_left_padding(1); - fort::table::default_props().set_cell_right_padding(1); - fort::table::default_props().set_cell_empty_str_height(0); + fort::char_table::default_props().set_cell_top_padding(1); + fort::char_table::default_props().set_cell_bottom_padding(1); + fort::char_table::default_props().set_cell_left_padding(1); + fort::char_table::default_props().set_cell_right_padding(1); + fort::char_table::default_props().set_cell_empty_str_height(0); - fort::table table = create_cpp_test_int_table(false); + fort::char_table table = create_cpp_test_int_table(false); table << ""; std::string table_str = table.to_string(); @@ -328,7 +328,7 @@ void test_cpp_table_cell_properties(void) WHEN("Setting properties for a particular table") { set_test_properties_as_default(); - fort::table table = create_cpp_test_int_table(false); + fort::char_table table = create_cpp_test_int_table(false); table.set_cell_bottom_padding(0); table.set_cell_top_padding(0); table.set_cell_left_padding(0); @@ -371,7 +371,7 @@ void test_cpp_table_cell_properties(void) WHEN("Set table width and column alignment") { set_test_properties_as_default(); - fort::table table = create_cpp_test_int_table(false); + fort::char_table table = create_cpp_test_int_table(false); table.column(1).set_cell_min_width(7); table.column(1).set_cell_text_align(fort::text_align::left); @@ -401,10 +401,10 @@ void test_cpp_table_cell_properties(void) WHEN("Set table width and column alignment as default") { set_test_properties_as_default(); - fort::table::default_props().set_cell_min_width(5); - fort::table::default_props().set_cell_text_align(fort::text_align::center); + fort::char_table::default_props().set_cell_min_width(5); + fort::char_table::default_props().set_cell_text_align(fort::text_align::center); - fort::table table = create_cpp_test_int_table(false); + fort::char_table table = create_cpp_test_int_table(false); std::string table_str = table.to_string(); std::string table_str_etalon = "+-----+-----+-----+-----+\n" @@ -426,7 +426,7 @@ void test_cpp_table_cell_properties(void) WHEN("Multiline cell") { set_test_properties_as_default(); - fort::table table; + fort::char_table table; table[0].set_cell_row_type(fort::row_type::header); table << 4 << 'c' << "234" << 3.14 << fort::endr; @@ -454,7 +454,7 @@ void test_cpp_table_cell_properties(void) WHEN("Cells with spans") { set_test_properties_as_default(); - fort::table table; + fort::char_table table; table[0][0].set_cell_span(5); table[1][1].set_cell_span(3); @@ -499,7 +499,7 @@ void test_cpp_table_cell_properties(void) WHEN("Cells with spans in common and header cells") { set_test_properties_as_default(); - fort::table table; + fort::char_table table; table.set_border_style(FT_DOUBLE2_STYLE); @@ -550,7 +550,7 @@ void test_cpp_table_text_styles(void) set_test_properties_as_default(); WHEN("Simple table with one cell and foreground content color") { - fort::table table; + fort::char_table table; table[0][0].set_cell_content_fg_color(fort::color::yellow); table << 42; @@ -566,7 +566,7 @@ void test_cpp_table_text_styles(void) } WHEN("Simple table with one cell and background content color") { - fort::table table; + fort::char_table table; table[0][0].set_cell_content_bg_color(fort::color::yellow); table << 42; @@ -582,7 +582,7 @@ void test_cpp_table_text_styles(void) } WHEN("Simple table with one cell and background cell color") { - fort::table table; + fort::char_table table; table[0][0].set_cell_bg_color(fort::color::yellow); table << 42; @@ -598,7 +598,7 @@ void test_cpp_table_text_styles(void) } WHEN("Simple table with one cell and content style") { - fort::table table; + fort::char_table table; table[0][0].set_cell_content_text_style(fort::text_style::underlined); table << 42; @@ -614,7 +614,7 @@ void test_cpp_table_text_styles(void) } WHEN("Simple table with one cell and multiple content style") { - fort::table table; + fort::char_table table; table[0][0].set_cell_content_text_style(fort::text_style::underlined); table[0][0].set_cell_content_text_style(fort::text_style::bold); @@ -631,7 +631,7 @@ void test_cpp_table_text_styles(void) } WHEN("Simple table with one cell and cell style") { - fort::table table; + fort::char_table table; table[0][0].set_cell_text_style(fort::text_style::underlined); table << 42; @@ -647,7 +647,7 @@ void test_cpp_table_text_styles(void) } WHEN("Simple table with one cell and multiple cell style") { - fort::table table; + fort::char_table table; table[0][0].set_cell_text_style(fort::text_style::underlined); table[0][0].set_cell_text_style(fort::text_style::bold); @@ -664,7 +664,7 @@ void test_cpp_table_text_styles(void) } WHEN("Simple table with one cell background color, content foreground color and style.") { - fort::table table; + fort::char_table table; table[0][0].set_cell_content_fg_color(fort::color::yellow); table[0][0].set_cell_bg_color(fort::color::red); diff --git a/tests/test_utils.cpp b/tests/test_utils.cpp index 9b0b38e..4ea9805 100644 --- a/tests/test_utils.cpp +++ b/tests/test_utils.cpp @@ -2,7 +2,7 @@ #include "tests.h" -bool set_cpp_test_props_for_table(fort::table *table) +bool set_cpp_test_props_for_table(fort::char_table *table) { assert_true(table->set_cell_bottom_padding(1)); assert_true(table->set_cell_top_padding(1)); @@ -33,9 +33,9 @@ bool set_cpp_test_props_for_table(fort::table *table) -fort::table create_cpp_test_int_table(int set_test_opts) +fort::char_table create_cpp_test_int_table(int set_test_opts) { - fort::table table; + fort::char_table table; if (set_test_opts) { assert_true(set_cpp_test_props_for_table(&table) == true); @@ -54,14 +54,14 @@ int set_test_properties_as_default(void) { bool status = true; - status = status && fort::table::default_props().set_cell_min_width(0); - status = status && fort::table::default_props().set_cell_text_align(fort::text_align::right); + status = status && fort::char_table::default_props().set_cell_min_width(0); + status = status && fort::char_table::default_props().set_cell_text_align(fort::text_align::right); - status = status && fort::table::default_props().set_cell_bottom_padding(1); - status = status && fort::table::default_props().set_cell_top_padding(1); - status = status && fort::table::default_props().set_cell_left_padding(1); - status = status && fort::table::default_props().set_cell_right_padding(1); - status = status && fort::table::default_props().set_cell_empty_str_height(1); + status = status && fort::char_table::default_props().set_cell_bottom_padding(1); + status = status && fort::char_table::default_props().set_cell_top_padding(1); + status = status && fort::char_table::default_props().set_cell_left_padding(1); + status = status && fort::char_table::default_props().set_cell_right_padding(1); + status = status && fort::char_table::default_props().set_cell_empty_str_height(1); assert_true(status == true); diff --git a/tests/test_utils.hpp b/tests/test_utils.hpp index 5dbed24..ef46f6e 100644 --- a/tests/test_utils.hpp +++ b/tests/test_utils.hpp @@ -1,15 +1,11 @@ #ifndef TEST_UTILS_HPP #define TEST_UTILS_HPP - -namespace fort -{ -class table; -} +#include "fort.hpp" int set_test_properties_as_default(void); -bool set_cpp_test_props_for_table(fort::table *table); -fort::table create_cpp_test_int_table(int set_test_opts); +bool set_cpp_test_props_for_table(fort::char_table *table); +fort::char_table create_cpp_test_int_table(int set_test_opts);