Skip to content

Commit

Permalink
Made parseTo2DArray() const; improved compile-time example to include…
Browse files Browse the repository at this point in the history
… escaped quotes.
  • Loading branch information
ashaduri committed Feb 12, 2021
1 parent c0acb9a commit 2d7629e
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 22 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ using namespace std::string_view_literals;
constexpr std::string_view data = "\"abc\",def\n5,6"sv;
constexpr std::size_t columns = 2, rows = 2;
Csv::Parser parser;
constexpr Csv::Parser parser;
// parse into std::array<std::array<CellStringReference, rows>, columns>
constexpr auto matrix = parser.parseTo2DArray<columns, rows>(data);
Expand Down
29 changes: 14 additions & 15 deletions csv_parser/csv_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,6 @@ namespace Csv {
* - Line ending format inside strings is preserved.
* - getOriginalStringView() methods may return escaped double-quotes; string_views are read-only and we
* cannot touch the original CSV data; use getCleanString() methods if you need unescaped data.
*
* Ambiguity notice:
* Empty cell (Invalid QVariant) and empty string (empty std::string) are serialized the same by Excel.
* We read them as Invalid QVariants, but QVariant::toByteArray() will give empty std::strings as expected.
*/
class Parser {
public:
Expand Down Expand Up @@ -93,7 +89,7 @@ class Parser {
/// \return std::array<std::array<Cell, rows>, columns>
/// \throws ParseError
template<std::size_t columns, std::size_t rows, typename Cell = CellStringReference>
constexpr auto parseTo2DArray(std::string_view data);
constexpr auto parseTo2DArray(std::string_view data) const;


private:
Expand Down Expand Up @@ -428,29 +424,32 @@ template<typename Vector2D>
constexpr void Parser::parseTo(std::string_view data, Vector2D& values) const
{
Vector2D parsed_values;
parse(data, [&](std::size_t row, std::size_t column, std::string_view cell_data, CellTypeHint hint) {
if (parsed_values.size() < (column + 1)) {
parsed_values.resize(column + 1);
}
if (parsed_values[column].size() < (row + 1)) {
parsed_values[column].resize(row + 1);
parse(data,
[&parsed_values](std::size_t row, std::size_t column, std::string_view cell_data, CellTypeHint hint)
{
if (parsed_values.size() < (column + 1)) {
parsed_values.resize(column + 1);
}
if (parsed_values[column].size() < (row + 1)) {
parsed_values[column].resize(row + 1);
}
parsed_values[column][row] = typename Vector2D::value_type::value_type(cell_data, hint);
}
parsed_values[column][row] = typename Vector2D::value_type::value_type(cell_data, hint);
});
);
std::swap(values, parsed_values);
}



template<std::size_t columns, std::size_t rows, typename Cell>
constexpr auto Parser::parseTo2DArray(std::string_view data)
constexpr auto Parser::parseTo2DArray(std::string_view data) const
{
std::array<std::array<Cell, rows>, columns> matrix;

parse(data,
[&matrix](std::size_t row, std::size_t column,
std::string_view cell_data, Csv::CellTypeHint hint)
constexpr mutable
constexpr
{
matrix[column][row] = Cell(cell_data, hint);
}
Expand Down
14 changes: 9 additions & 5 deletions examples/example_compiletime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,23 @@ int main()
{
using namespace std::string_view_literals;

constexpr std::string_view data = "\"abc\",def\n5,6"sv;
constexpr std::string_view data =
R"(abc,5
,"with ""quote inside"
)"sv;
constexpr std::size_t columns = 2, rows = 2;

Csv::Parser parser;
constexpr Csv::Parser parser;

// parse into std::array<std::array<CellStringReference, rows>, columns>
constexpr auto matrix = parser.parseTo2DArray<columns, rows>(data);

// Verify the data at compile time.
static_assert(matrix[0][0].getOriginalStringView() == "abc"sv);
static_assert(matrix[1][0].getOriginalStringView() == "def"sv);
static_assert(matrix[0][1].getOriginalStringView() == "5"sv);
static_assert(matrix[1][1].getOriginalStringView() == "6"sv);
static_assert(matrix[1][0].getOriginalStringView() == "5"sv);
static_assert(matrix[0][1].getOriginalStringView().empty());
static_assert(matrix[1][1].getCleanStringBuffer<"with \"\"quote inside"sv.size()>().getStringView()
== "with \"quote inside"sv);

return EXIT_SUCCESS;
}
Expand Down
2 changes: 1 addition & 1 deletion tests/test_csv_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ TEST_CASE("CsvParser", "[csv][parser]")

SECTION("supports constexpr") {
constexpr std::string_view data = "\"abc\",def\n\"with \"\"quote inside\",6"sv;
Csv::Parser parser;
constexpr Csv::Parser parser;

// parse into std::array<std::array<CellStringReference, rows>, columns>
constexpr auto matrix = parser.parseTo2DArray<2, 2>(data);
Expand Down

0 comments on commit 2d7629e

Please sign in to comment.