Skip to content

Commit 6b68f66

Browse files
Epiread: added a constructor to make an epiread from a line from a states file
1 parent 8827bab commit 6b68f66

1 file changed

Lines changed: 40 additions & 0 deletions

File tree

src/common/Epiread.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <string>
1919
#include <stdexcept>
2020
#include <fstream>
21+
#include <charconv>
2122

2223
#include "Epiread.hpp"
2324

@@ -76,3 +77,42 @@ validate_epiread_file(const string &filename) {
7677
}
7778
return true;
7879
}
80+
81+
epiread::epiread(const string &line) {
82+
constexpr auto is_sep = [](const char x) { return x == ' ' || x == '\t'; };
83+
constexpr auto not_sep = [](const char x) { return x != ' ' && x != '\t'; };
84+
85+
using std::find_if;
86+
using std::from_chars;
87+
using std::distance;
88+
89+
bool failed = false;
90+
91+
const auto c = line.data();
92+
const auto c_end = c + line.size();
93+
94+
auto field_s = c;
95+
auto field_e = find_if(field_s + 1, c_end, is_sep);
96+
if (field_e == c_end) failed = true;
97+
98+
chr = string{field_s, static_cast<uint32_t>(distance(field_s, field_e))};
99+
100+
field_s = find_if(field_e + 1, c_end, not_sep);
101+
field_e = find_if(field_s + 1, c_end, is_sep);
102+
failed = failed || (field_e == c_end);
103+
104+
const auto [ptr, ec] = from_chars(field_s, field_e, pos);
105+
failed = failed || (ptr == field_s);
106+
107+
field_s = find_if(field_e + 1, c_end, not_sep);
108+
field_e = find_if(field_s + 1, c_end, is_sep);
109+
failed = failed || (field_e != c_end);
110+
111+
seq = string{field_s, static_cast<uint32_t>(distance(field_s, field_e))};
112+
113+
if (failed) {
114+
throw std::runtime_error("bad epiread line: " + line);
115+
// ADS: the value below would work for a flag
116+
// pos = std::numeric_limits<decltype(pos)>::max();
117+
}
118+
}

0 commit comments

Comments
 (0)