alpaqa 1.0.0a9
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
101#ifdef ALPAQA_WITH_QUAD_PRECISION
102template <>
103const char *CSVReader<__float128>::read_single(const char *bufbegin,
104 const char *bufend,
105 __float128 &v) {
106 long double ld;
107 auto ret = CSVReader<long double>::read_single(bufbegin, bufend, ld);
108 v = static_cast<__float128>(ld);
109 return ret;
110}
111#endif
112
113template <std::floating_point F>
114void read_row_impl(std::istream &is, Eigen::Ref<Eigen::VectorX<F>> v,
115 char sep) {
116 CSVReader<F> reader;
117 for (auto &vv : v)
118 vv = reader.read(is, sep);
119 reader.check_end(is);
120}
121
122template <std::floating_point F>
123std::vector<F> read_row_std_vector(std::istream &is, char sep) {
124 CSVReader<F> reader;
125 std::vector<F> v;
126 while (!reader.done(is))
127 v.push_back(reader.read(is, sep));
128 reader.check_end(is);
129 return v;
130}
131
132} // namespace alpaqa::csv
std::vector< F > read_row_std_vector(std::istream &is, char sep)
Definition: csv.tpp:123
void read_row_impl(std::istream &is, Eigen::Ref< Eigen::VectorX< F > > v, char sep)
Definition: csv.tpp:114
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