alpaqa pantr
Nonconvex constrained optimization
Loading...
Searching...
No Matches
csv.tpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <cassert>
5#include <charconv>
6#include <ios>
7#include <iostream>
8
9#if !__cpp_lib_to_chars
10#include <cerrno>
11#include <cstdlib> // strtod
12#endif
13
14namespace alpaqa::csv {
15
16template <std::floating_point F>
17struct CSVReader {
18 static constexpr std::streamsize bufmaxsize = 64;
19 std::array<char, bufmaxsize + 1> s;
20 std::streamsize bufidx = 0;
21 bool keep_reading = true;
22 static constexpr char end = '\n';
23
24 [[nodiscard]] F read(std::istream &is, char sep) {
25 // Get some characters to process
26 if (keep_reading) {
27 if (!is.get(s.data() + bufidx, bufmaxsize - bufidx, end))
28 throw read_error("csv::read_row extraction failed: " +
29 std::to_string(is.bad()) + " " +
30 std::to_string(is.fail()) + " " +
31 std::to_string(is.eof()));
32 bufidx += is.gcount();
33 keep_reading = is.peek() != end && !is.eof();
34 assert(bufidx < bufmaxsize);
35 }
36 // Parse a number
37 F v;
38 char *bufend = s.data() + bufidx;
39 const char *ptr = read_single(s.data(), bufend, v);
40 // Check separator
41 if (ptr != bufend && *ptr != sep)
42 throw read_error("csv::read_row unexpected character '" +
43 std::string{*ptr} + "'");
44 // Shift the buffer over
45 if (ptr != bufend) {
46 std::copy(ptr + 1, static_cast<const char *>(bufend), s.data());
47 bufidx -= ptr + 1 - s.data();
48 } else {
49 bufidx = 0;
50 }
51 return v;
52 }
53
54#if __cpp_lib_to_chars
55 static const char *read_single(const char *bufbegin, const char *bufend,
56 F &v) {
57 if (bufbegin != bufend && *bufbegin == '+')
58 ++bufbegin;
59 const auto [ptr, ec] = std::from_chars(bufbegin, bufend, v);
60 const auto bufvw = std::string_view(bufbegin, bufend);
61 if (ec != std::errc{})
62 throw read_error("csv::read_row conversion failed '" +
63 std::string(bufvw) +
64 "': " + std::make_error_code(ec).message());
65 return ptr;
66 }
67#else
68 static void strtod_ovl(const char *str, char **str_end, float &v) {
69 v = std::strtof(str, str_end);
70 }
71 static void strtod_ovl(const char *str, char **str_end, double &v) {
72 v = std::strtod(str, str_end);
73 }
74 static void strtod_ovl(const char *str, char **str_end, long double &v) {
75 v = std::strtold(str, str_end);
76 }
77 static const char *read_single(const char *bufbegin, char *bufend, F &v) {
78 *bufend = '\0';
79 char *ptr;
80 errno = 0;
81 strtod_ovl(bufbegin, &ptr, v);
82 if (errno || ptr == bufbegin)
83 throw read_error("csv::read_row conversion failed '" +
84 std::string(bufbegin) +
85 "': " + std::to_string(errno));
86 return ptr;
87 }
88#endif
89
90 void check_end(std::istream &is) const {
91 if (bufidx > 0 || (is.get() != end && is))
92 throw read_error("csv::read_row line not fully consumed");
93 }
94
95 [[nodiscard]] bool done(std::istream &is) const {
96 bool keep_reading = is.peek() != end && !is.eof();
97 return bufidx == 0 && !keep_reading;
98 }
99};
100
101template <std::floating_point F>
102void read_row_impl(std::istream &is, Eigen::Ref<Eigen::VectorX<F>> v,
103 char sep) {
104 CSVReader<F> reader;
105 for (auto &vv : v)
106 vv = reader.read(is, sep);
107 reader.check_end(is);
108}
109
110template <std::floating_point F>
111std::vector<F> read_row_std_vector(std::istream &is, char sep) {
112 CSVReader<F> reader;
113 std::vector<F> v;
114 while (!reader.done(is))
115 v.push_back(reader.read(is, sep));
116 reader.check_end(is);
117 return v;
118}
119
120} // namespace alpaqa::csv
std::vector< F > read_row_std_vector(std::istream &is, char sep)
Definition: csv.tpp:111
void read_row_impl(std::istream &is, Eigen::Ref< Eigen::VectorX< F > > v, char sep)
Definition: csv.tpp:102
static constexpr std::streamsize bufmaxsize
Definition: csv.tpp:18
static const char * read_single(const char *bufbegin, char *bufend, F &v)
Definition: csv.tpp:77
bool done(std::istream &is) const
Definition: csv.tpp:95
std::array< char, bufmaxsize+1 > s
Definition: csv.tpp:19
F read(std::istream &is, char sep)
Definition: csv.tpp:24
static constexpr char end
Definition: csv.tpp:22
static void strtod_ovl(const char *str, char **str_end, double &v)
Definition: csv.tpp:71
std::streamsize bufidx
Definition: csv.tpp:20
static void strtod_ovl(const char *str, char **str_end, long double &v)
Definition: csv.tpp:74
static void strtod_ovl(const char *str, char **str_end, float &v)
Definition: csv.tpp:68
void check_end(std::istream &is) const
Definition: csv.tpp:90