I'm writing a library of IO functions for my physics laboratory class. In the meanwhile, I'm hoping to learn more about generic programming and C++20 concepts.
Some context
I usually came home from the lab with a .txt
file that looks like
value value value ... value value value ...
where each line represents a set of repeated measurements of the same physical quantity.
I want to write a function that reads one line at a time from my .txt
and put all the values it founds into some vector. My idea is to mock getline
The actual code
#include <algorithm> // for std::transform #include <fstream> // for std::ifstream #include <iterator> // for std::istream_iterator #include <sstream> // for std::istringstream #include <string> // for std::string and std::getline #include <type_traits> // for std::is_arithmetic_v #include <vector> // for std::vector
template<typename T> concept Arithmetic = std::is_arithmetic_v<T>;
namespace sf { namespace io { template <Arithmetic T> std::vector<T> getline(std::ifstream& data) { std::vector<T> meas; std::string line{}; while (line.size() == 0 && !data.eof()) { std::getline(data, line); } std::istringstream lines{line}; std::istream_iterator<std::string> linei{lines}; std::transform(linei, std::istream_iterator<std::string>{}, std::back_inserter(meas), [] (std::string s) {return std::stod(s);}); return meas; } } } // namespace io // namespace sf
I.e., I first define a new concept for "arithmetic" types, and then I write a generic function that
- eats a file
- tries reading a line until we've got to an actual nonempty line or to
eof
- parses whatever it got, and puts it into a
std::vector
.
I'm planning to use my code like this
std::string path = "path/to/data.txt" std::ifstream file(path); auto meas1 = sf::io::getline<double>(file); auto meas2 = sf::io::getline<double>(file); // and so on
What I already know my code does not achieve
- First of all, I would like to make my code less dependent on the
vector
class. - At some point I use the standard library's
stod
function. There is at least another way of parsing number literals from strings to actual arithmetic types... but am I on the right path? I read that one could achieve exactly what I am trying to achieve, in a more idiomatic way, by the means of the>>
operator...