I'm using the ben strasser C++ fast csv parser: https://github.com/ben-strasser/fast-cpp-csv-parser. It uses a variadic template to pass column values back to the while loop that processes the csv data:
io::CSVReader<2> in(csv_filename);
double x, y;
while(in.read_row(x,y)) {
//code with x and y
}
This calls the following function in the CSVReader class:
template<class ...ColType>
bool read_row(ColType& ...cols){
//snip
}
This works fine for me with my x and y values. However, I would like to expand this to use arbitrary dimensions. This means my data has a (known) number of columns I need to read. I would like to use something like this:
io::CSVReader<known_dimension> in(csvfname);
double data[known_dimension];
while(in.read_row(data)) {
//code with data[0],data[1],...,data[known_number]
}
However, this is not valid syntax. I need to "unpack" the array of doubles into separate arguments of pointers to my doubles. I'd like to do this without modifications to the fast csv parser.
You can use std::integer_sequence
for that purpose:
namespace Detail
{
template <typename Reader, typename T, std::size_t... I>
void read_row(Reader& in, T* data, std::index_sequence<I...>)
{
in.read_row(data[I]...); // A trick here
}
}
template <std::size_t N, typename T>
void read_row(io::CSVReader<N>& in, T* data)
{
Detail::read_row(in, data, std::make_index_sequence<N>{});
}
And of course, use like this:
int a[7];
io::CSVReader<7> r;
read_row(r, a);
"Working" example: link
For compiler "below" C++14 - integer_sequence
(actually just index_sequence
needed) is pretty easy to implement:
template <std::size_t... I>
class index_sequence {};
And make_index_sequence
not so easy - but also doable:
template <std::size_t N, std::size_t ...I>
struct make_index_sequence : make_index_sequence<N-1, N-1,I...> {};
template <std::size_t ...I>
struct make_index_sequence<0,I...> : index_sequence<I...> {};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With