diff --git a/source/module_base/formatter.h b/source/module_base/formatter.h index 963964f0ef5..5935cd9eeaf 100644 --- a/source/module_base/formatter.h +++ b/source/module_base/formatter.h @@ -191,17 +191,22 @@ class FmtTable * * @param titles titles, its size should be the same as the number of columns * @param nrows number of rows - * @param aligns Alignments instance, can be constructed with initializer_list like {'r', 'c'}, for right and center alignment for values and titles + * @param fmts format strings for each column, its size should be the same as the number of columns + * @param indent indent for each column, default is 0 + * @param aligns Alignments instance, for alignment of values and titles, e.g. {Align::LEFT, Align::RIGHT} for left alignment of values and right alignment of titles * @param frames Frames instance, can be constructed with initializer_list like {'-', '-', '-', ' ', ' '}, for up, middle, down, left and right frames * @param delimiters Delimiters instance, can be constructed with initializer_list like {'-', ' '}, for horizontal and vertical delimiters */ FmtTable(const std::vector& titles, - const size_t& nrows, + const size_t nrows, const std::vector& fmts, + const size_t indent = 0, const Alignments& aligns = {}, const Frames& frames = {}, - const Delimiters& delimiters = {}): titles_(titles), data_(nrows, titles.size()), fmts_(fmts), aligns_(aligns), frames_(frames), delimiters_(delimiters) - { assert(titles.size() == fmts.size()); }; + const Delimiters& delimiters = {}): + titles_(titles), data_(nrows, titles.size()), // data + fmts_(fmts), indent_(indent), aligns_(aligns), frames_(frames), delimiters_(delimiters) // styles + { assert(titles.size() == fmts.size()||titles.size() == 0); }; ~FmtTable() {}; /** * @brief import data from std::vector @@ -269,14 +274,15 @@ class FmtTable */ std::string concat_title(const std::vector& titles) const { - std::string dst; + std::string dst = ""; // first sum width of all titles size_t width = std::accumulate(titles.begin(), titles.end(), 0, [](const size_t& acc, const std::string& s) { return acc + s.size(); }); // add width of delimiters width += titles.size() - 1; // add width of left and right frames width += 2; - dst += std::string(width, frames_.up_) + "\n" + std::string(1, frames_.l_); + dst += std::string(indent_, ' ') + std::string(width, frames_.up_) + "\n"; // first line: the upper frame + dst += std::string(indent_, ' ') + std::string(1, frames_.l_); // second line: the left frame + titles + right frame for(size_t i = 0; i < titles.size(); i++) { dst += titles[i]; @@ -284,7 +290,8 @@ class FmtTable dst += delimiters_.v_; } } - dst += std::string(1, frames_.r_) + "\n" + std::string(width, frames_.mid_) + "\n"; + dst += std::string(1, frames_.r_) + "\n"; + dst += std::string(indent_, ' ') + std::string(width, frames_.mid_) + "\n"; // third line: the middle frame return dst; } /** @@ -303,10 +310,10 @@ class FmtTable width += row.size() - 1; // for the left and right frame width += 2; - if (pos == 't') { - dst += std::string(width, frames_.up_) + "\n"; + if (pos == 't') { // 't' for top + dst += std::string(indent_, ' ') + std::string(width, frames_.up_) + "\n"; } - dst += std::string(1, frames_.l_); + dst += std::string(indent_, ' ') + std::string(1, frames_.l_); for(size_t i = 0; i < row.size(); i++) { dst += row[i]; @@ -315,8 +322,8 @@ class FmtTable } } dst += std::string(1, frames_.r_) + "\n"; - if (pos == 'b') { - dst += std::string(width, frames_.dw_) + "\n"; + if (pos == 'b') { // 'b' for bottom + dst += std::string(indent_, ' ') + std::string(width, frames_.dw_) + "\n"; // the last line } return dst; } @@ -397,6 +404,7 @@ class FmtTable std::vector titles_; NDArray data_; // data std::vector fmts_; // format strings for each column + size_t indent_ = 0; // indent for each column }; #endif \ No newline at end of file diff --git a/source/module_base/test/formatter_test.cpp b/source/module_base/test/formatter_test.cpp index 9a7fecddc0d..20696e13571 100644 --- a/source/module_base/test/formatter_test.cpp +++ b/source/module_base/test/formatter_test.cpp @@ -217,6 +217,28 @@ TEST(FormatterTest, FmtTableDefaultArgs) EXPECT_EQ(result, ref); } +TEST(FormatterTest, FmtTableHeadless) +{ + const std::vector titles = {"", "", ""}; + const std::vector fmts = {"%s", "%d", "%f"}; + FmtTable table(titles, 5, fmts); + const std::vector col1 = {"row1", "row2", "row3", "row4", "row5"}; + const std::vector col2 = {1, 2, 3, 4, 5}; + const std::vector col3 = {1.1, 2.2, 3.3, 4.4, 5.5}; + table << col1 << col2 << col3; + const std::string result = table.str(); + std::cout << result << std::endl; + std::string ref = ""; + ref += "-----------------\n"; + ref += " row1 1 1.100000 \n"; + ref += " row2 2 2.200000 \n"; + ref += " row3 3 3.300000 \n"; + ref += " row4 4 4.400000 \n"; + ref += " row5 5 5.500000 \n"; + ref += "-----------------\n"; + EXPECT_EQ(result, ref); +} + TEST(FormatterTest, FmtTableCustomArgsAlign) { // shared data @@ -226,7 +248,7 @@ TEST(FormatterTest, FmtTableCustomArgsAlign) std::vector col2 = {1, 2, 3, 4, 5}; std::vector col3 = {1.1, 2.2, 3.3, 4.4, 5.5}; // align: l and l - FmtTable table(titles, 5, fmts, {FmtTable::Align::LEFT, FmtTable::Align::LEFT}); + FmtTable table(titles, 5, fmts, 0, {FmtTable::Align::LEFT, FmtTable::Align::LEFT}); table << col1 << col2 << col3; std::string result = table.str(); std::cout << result << std::endl; @@ -243,7 +265,7 @@ TEST(FormatterTest, FmtTableCustomArgsAlign) EXPECT_EQ(result, ref); // align: r and r - FmtTable table2(titles, 5, fmts, {FmtTable::Align::RIGHT, FmtTable::Align::RIGHT}); + FmtTable table2(titles, 5, fmts, 0, {FmtTable::Align::RIGHT, FmtTable::Align::RIGHT}); table2 << col1 << col2 << col3; result = table2.str(); std::cout << result << std::endl; @@ -260,7 +282,7 @@ TEST(FormatterTest, FmtTableCustomArgsAlign) EXPECT_EQ(result, ref); // align: l and r - FmtTable table3(titles, 5, fmts, {FmtTable::Align::RIGHT, FmtTable::Align::LEFT}); + FmtTable table3(titles, 5, fmts, 0, {FmtTable::Align::RIGHT, FmtTable::Align::LEFT}); table3 << col1 << col2 << col3; result = table3.str(); std::cout << result << std::endl; @@ -277,7 +299,7 @@ TEST(FormatterTest, FmtTableCustomArgsAlign) EXPECT_EQ(result, ref); // align: r and l - FmtTable table4(titles, 5, fmts, {FmtTable::Align::LEFT, FmtTable::Align::RIGHT}); + FmtTable table4(titles, 5, fmts, 0, {FmtTable::Align::LEFT, FmtTable::Align::RIGHT}); table4 << col1 << col2 << col3; result = table4.str(); std::cout << result << std::endl; @@ -303,7 +325,12 @@ TEST(FormatterTest, FmtTableCustomArgsAlignFrame) std::vector col2 = {1, 2, 3, 4, 5}; std::vector col3 = {1.1, 2.2, 3.3, 4.4, 5.5}; - FmtTable table1(titles, 5, fmts, {FmtTable::Align::LEFT, FmtTable::Align::LEFT}, {'+', '?', '*', '.', '^'}); + FmtTable table1(titles, + 5, + fmts, + 0, + {FmtTable::Align::LEFT, FmtTable::Align::LEFT}, + {'+', '?', '*', '.', '^'}); table1 << col1 << col2 << col3; std::string result = table1.str(); std::cout << result << std::endl; @@ -328,7 +355,10 @@ TEST(FormatterTest, FmtTableCustomArgsAlignFrameDelim) std::vector col1 = {"row1", "row2", "row3", "row4", "row5"}; std::vector col2 = {1, 2, 3, 4, 5}; std::vector col3 = {1.1, 2.2, 3.3, 4.4, 5.5}; - FmtTable table1(titles, 5, fmts, + FmtTable table1(titles, + 5, + fmts, + 0, {FmtTable::Align::LEFT, FmtTable::Align::LEFT}, {'=', '/', '&', '#', '%'}, {'"', ']'}); @@ -348,6 +378,30 @@ TEST(FormatterTest, FmtTableCustomArgsAlignFrameDelim) EXPECT_EQ(result, ref); } +TEST(FormatterTest, FmtTableCustomIndent) +{ + const std::vector titles = {"title1", "t i t l e 2", "t-i-t-l-e-3"}; + const std::vector fmts = {"%s", "%d", "%f"}; + FmtTable table(titles, 5, fmts, 4); + const std::vector col1 = {"row1", "row2", "row3", "row4", "row5"}; + const std::vector col2 = {1, 2, 3, 4, 5}; + const std::vector col3 = {1.1, 2.2, 3.3, 4.4, 5.5}; + table << col1 << col2 << col3; + const std::string result = table.str(); + std::cout << result << std::endl; + std::string ref = ""; + ref += " --------------------------------\n"; + ref += " title1 t i t l e 2 t-i-t-l-e-3 \n"; + ref += " --------------------------------\n"; + ref += " row1 1 1.100000 \n"; + ref += " row2 2 2.200000 \n"; + ref += " row3 3 3.300000 \n"; + ref += " row4 4 4.400000 \n"; + ref += " row5 5 5.500000 \n"; + ref += " --------------------------------\n"; + EXPECT_EQ(result, ref); +} + int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/source/module_base/timer.cpp b/source/module_base/timer.cpp index 824f9235575..90bd6f3bf9a 100644 --- a/source/module_base/timer.cpp +++ b/source/module_base/timer.cpp @@ -300,7 +300,11 @@ void timer::print_all(std::ofstream &ofs) std::vector titles = {"CLASS_NAME", "NAME", "TIME/s", "CALLS", "AVG/s", "PER/%"}; std::vector formats = {"%-10s", "%-10s", "%6.2f", "%8d", "%6.2f", "%6.2f"}; - FmtTable time_statistics(titles, pers.size(), formats, {FmtTable::Align::LEFT, FmtTable::Align::CENTER}); + FmtTable time_statistics(/*titles=*/titles, + /*nrows=*/pers.size(), + /*formats=*/formats, + /*indent=*/0, + /*align=*/{/*value*/FmtTable::Align::LEFT, /*title*/FmtTable::Align::CENTER}); time_statistics << class_names << names << times << calls << avgs << pers; const std::string table = "TIME STATISTICS\n" + time_statistics.str(); std::cout< items = {"s6", "s8", "a1", "a2"}; vdwd3tab << items << flag << param; (*plog) << "\nDFT-D3 Dispersion correction parameters autoset\n" << vdwd3tab.str() diff --git a/source/module_hamilt_lcao/module_deltaspin/spin_constrain.cpp b/source/module_hamilt_lcao/module_deltaspin/spin_constrain.cpp index 1339fc46011..30500ccca9e 100644 --- a/source/module_hamilt_lcao/module_deltaspin/spin_constrain.cpp +++ b/source/module_hamilt_lcao/module_deltaspin/spin_constrain.cpp @@ -523,7 +523,11 @@ void SpinConstrain::print_Mi(std::ofstream& ofs_running) { const std::vector title = {"Total Magnetism (uB)", ""}; const std::vector fmts = {"%-26s", "%20.10f"}; - FmtTable table(title, nat, fmts, {FmtTable::Align::RIGHT, FmtTable::Align::LEFT}); + FmtTable table(/*titles=*/title, + /*nrows=*/nat, + /*formats=*/fmts, + /*indent=*/0, + /*align=*/{/*value*/FmtTable::Align::RIGHT, /*title*/FmtTable::Align::LEFT}); for (int iat = 0; iat < nat; ++iat) { mag_z[iat] = Mi_[iat].z; @@ -535,7 +539,11 @@ void SpinConstrain::print_Mi(std::ofstream& ofs_running) { const std::vector title = {"Total Magnetism (uB)", "", "", ""}; const std::vector fmts = {"%-26s", "%20.10f", "%20.10f", "%20.10f"}; - FmtTable table(title, nat, fmts, {FmtTable::Align::RIGHT, FmtTable::Align::LEFT}); + FmtTable table(/*titles=*/title, + /*nrows=*/nat, + /*formats=*/fmts, + /*indent=*/0, + /*align=*/{/*value*/FmtTable::Align::RIGHT, /*title*/FmtTable::Align::LEFT}); for (int iat = 0; iat < nat; ++iat) { mag_x[iat] = Mi_[iat].x; @@ -560,7 +568,11 @@ void SpinConstrain::print_Mag_Force(std::ofstream& ofs_running) { const std::vector title = {"Magnetic force (eV/uB)", ""}; const std::vector fmts = {"%-26s", "%20.10f"}; - FmtTable table(title, nat, fmts, {FmtTable::Align::RIGHT, FmtTable::Align::LEFT}); + FmtTable table(/*titles=*/title, + /*nrows=*/nat, + /*formats=*/fmts, + /*indent=*/0, + /*align=*/{/*value*/FmtTable::Align::RIGHT, /*title*/FmtTable::Align::LEFT}); for (int iat = 0; iat < nat; ++iat) { mag_force_z[iat] = lambda_[iat].z * ModuleBase::Ry_to_eV; @@ -572,7 +584,11 @@ void SpinConstrain::print_Mag_Force(std::ofstream& ofs_running) { const std::vector title = {"Magnetic force (eV/uB)", "", "", ""}; const std::vector fmts = {"%-26s", "%20.10f", "%20.10f", "%20.10f"}; - FmtTable table(title, nat, fmts, {FmtTable::Align::RIGHT, FmtTable::Align::LEFT}); + FmtTable table(/*titles=*/title, + /*nrows=*/nat, + /*formats=*/fmts, + /*indent=*/0, + /*align=*/{/*value*/FmtTable::Align::RIGHT, /*title*/FmtTable::Align::LEFT}); for (int iat = 0; iat < nat; ++iat) { mag_force_x[iat] = lambda_[iat].x * ModuleBase::Ry_to_eV; diff --git a/source/module_hamilt_pw/hamilt_pwdft/onsite_projector.cpp b/source/module_hamilt_pw/hamilt_pwdft/onsite_projector.cpp index 348ada66330..c69484c012b 100644 --- a/source/module_hamilt_pw/hamilt_pwdft/onsite_projector.cpp +++ b/source/module_hamilt_pw/hamilt_pwdft/onsite_projector.cpp @@ -590,7 +590,11 @@ void projectors::OnsiteProjector::cal_occupations(const psi::Psi title = {"Total Magnetism (uB)", "", "", ""}; const std::vector fmts = {"%-26s", "%20.10f", "%20.10f", "%20.10f"}; const std::vector orb_names = {"s", "p", "d", "f", "g"}; - FmtTable table(title, this->ucell->nat, fmts, {FmtTable::Align::RIGHT, FmtTable::Align::LEFT}); + FmtTable table(/*titles=*/title, + /*nrows=*/this->ucell->nat, + /*formats=*/fmts, + /*indent=*/0, + /*align=*/{/*value*/FmtTable::Align::RIGHT, /*title*/FmtTable::Align::LEFT}); // parameters for mag output int occ_index = 0; for(int iat=0;iatucell->nat;iat++) diff --git a/source/module_io/output_log.cpp b/source/module_io/output_log.cpp index 7bf3a08d993..bd1a1afce8b 100644 --- a/source/module_io/output_log.cpp +++ b/source/module_io/output_log.cpp @@ -242,7 +242,9 @@ void print_force(std::ofstream& ofs_running, } } - FmtTable fmt(titles, atom_label.size(), {"%10s", "%20.10f", "%20.10f", "%20.10f"}); + FmtTable fmt(/*titles=*/titles, + /*nrows=*/atom_label.size(), + /*formats=*/{"%10s", "%20.10f", "%20.10f", "%20.10f"}, 0); fmt << atom_label << force_x << force_y << force_z; table = fmt.str(); ofs_running << table << std::endl; @@ -283,7 +285,9 @@ void print_stress(const std::string& name, const ModuleBase::matrix& scs, const double pressure = (scs(0, 0) + scs(1, 1) + scs(2, 2)) / 3.0 * unit_transform; - FmtTable fmt(titles, 3, {"%20.10f", "%20.10f", "%20.10f"}); + FmtTable fmt(/*titles=*/titles, + /*nrows=*/3, + /*formats=*/{"%20.10f", "%20.10f", "%20.10f"}, 0); fmt << stress_x << stress_y << stress_z; table = fmt.str(); GlobalV::ofs_running << table; diff --git a/source/module_io/output_mulliken.cpp b/source/module_io/output_mulliken.cpp index 3de113059bd..8a31995b403 100644 --- a/source/module_io/output_mulliken.cpp +++ b/source/module_io/output_mulliken.cpp @@ -440,7 +440,11 @@ void Output_Mulliken::print_atom_mag(const std::vector>& { const std::vector title = {"Total Magnetism (uB)", ""}; const std::vector fmts = {"%-26s", "%20.10f"}; - FmtTable table(title, nat, fmts, {FmtTable::Align::RIGHT, FmtTable::Align::LEFT}); + FmtTable table(/*titles=*/title, + /*nrows=*/nat, + /*formats=*/fmts, + /*indent=*/0, + /*align=*/{/*value*/FmtTable::Align::RIGHT, /*title*/FmtTable::Align::LEFT}); for (int iat = 0; iat < nat; ++iat) { atom_label.push_back(this->cell_index_->get_atom_label(iat, true)); @@ -456,7 +460,11 @@ void Output_Mulliken::print_atom_mag(const std::vector>& std::vector azimuth(nat, 0.0); const std::vector title = {"Total Magnetism (uB)", "x", "y", "z"}; const std::vector fmts = {"%26s", "%20.10f", "%20.10f", "%20.10f"}; - FmtTable table(title, nat, fmts, {FmtTable::Align::RIGHT, FmtTable::Align::RIGHT}); + FmtTable table(/*titles=*/title, + /*nrows=*/nat, + /*formats=*/fmts, + /*indent=*/0, + /*align=*/{/*value*/FmtTable::Align::RIGHT, /*title*/FmtTable::Align::RIGHT}); for (int iat = 0; iat < nat; ++iat) { atom_label.push_back(this->cell_index_->get_atom_label(iat, true)); @@ -472,7 +480,11 @@ void Output_Mulliken::print_atom_mag(const std::vector>& /// output mag in polar coordinates const std::vector title_polar = {"Total Magnetism (uB)", "Magnitude (uB)", "Polar (degree)", "Azimuth (degree)"}; const std::vector fmts_polar = {"%26s", "%20.10f", "%20.10f", "%20.10f"}; - FmtTable table_polar(title_polar, nat, fmts_polar, {FmtTable::Align::RIGHT, FmtTable::Align::RIGHT}); + FmtTable table_polar(/*titles=*/title_polar, + /*nrows=*/nat, + /*formats=*/fmts_polar, + /*indent=*/0, + /*align=*/{/*value*/FmtTable::Align::RIGHT, /*title*/FmtTable::Align::RIGHT}); table_polar << atom_label << magnitude << polar << azimuth; os << table_polar.str() << std::endl; }