diff --git a/src/lib/stat/csv.hpp b/src/lib/stat/csv.hpp index da84a95e0..bc6ef477b 100644 --- a/src/lib/stat/csv.hpp +++ b/src/lib/stat/csv.hpp @@ -51,7 +51,6 @@ #include "lib/null-value.hpp" #include "lib/meta/tuple-helper.hpp" #include "lib/format-string.hpp" -#include "lib/format-util.hpp" #include "lib/regex.hpp" #include @@ -170,7 +169,10 @@ namespace stat { operator string() const { - return util::join (*this, "\n"); + std::ostringstream buffer; + for (string const& line : *this) + buffer << line << '\n'; + return buffer.str(); } diff --git a/src/lib/stat/data.hpp b/src/lib/stat/data.hpp index bcb7407b8..932d67472 100644 --- a/src/lib/stat/data.hpp +++ b/src/lib/stat/data.hpp @@ -71,7 +71,13 @@ ** ** std::vector& counters = daz.n.data; ** \endcode - ** + ** \par Variations + ** The standard case is to have a table backed by persistent file storage, + ** which can be initially empty. Under some conditions, especially for tests + ** - the DataFile can be created without filename + ** - it can be created from a CSVData, which is a `std::vector` of CSV-strings + ** - it can be [rendered into CSV strings](\ref #renderCSV) + ** - a (new) storage file name can be [given later](\ref saveAs) ** @see DataCSV_test ** */ @@ -198,6 +204,12 @@ namespace stat{ loadData(); } + DataFile (CSVData const& csv) + : filename_{} + { + appendFrom (csv); + } + /* === Data Access === */ @@ -222,12 +234,15 @@ namespace stat{ return rowCnt; } - string - dumpCSV() const + CSVData + renderCSV() const { - string csv; + CSVData csv{{}}; + csv.reserve (size()+1); + auto header = generateHeaderSpec(); + std::swap (csv[0], header); for (uint i=0; i < size(); ++i) - csv += formatCSVRow(i) + '\n'; + csv.emplace_back (formatCSVRow(i)); return csv; } @@ -291,6 +306,17 @@ namespace stat{ }); } + void + appendFrom (CSVData const& csv) + { + if (isnil (csv)) return; + verifyHeaderSpec (csv[0]); + for (size_t row=1; rowempty()) @@ -457,11 +483,11 @@ namespace stat{ throw error::Logic{_Fmt{"Attempt to access row #%d beyond range [0..%d]."} % rownum % (size()-1)}; - string csvLine; + CSVLine csvLine; forAllColumns( [&](auto& col) { - appendCsvField (csvLine, col.data.at(rownum)); + csvLine += col.data.at(rownum); }); return csvLine; } diff --git a/tests/library/gnuplot-gen-test.cpp b/tests/library/gnuplot-gen-test.cpp index d4dd02b16..6ddacf6fe 100644 --- a/tests/library/gnuplot-gen-test.cpp +++ b/tests/library/gnuplot-gen-test.cpp @@ -65,7 +65,7 @@ namespace test{ /** @test TODO - * @todo WIP 4/24 🔁 define ⟶ implement + * @todo WIP 4/24 🔁 define ⟶ ✔ implement */ void simpeUsage() @@ -78,12 +78,13 @@ namespace test{ ,{4,5} ,{5,8} ,{6,13} - ,{7,21} + ,{7,21.55} }}); cout << gnuplot < - - + + + + + + + + @@ -112186,8 +112192,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -112203,8 +112209,17 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + + + + + + + + + +
@@ -112260,10 +112275,6 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - - @@ -114421,9 +114432,16 @@ std::cout << tmpl.render({"what", "World"}) << s + + + + + + +