26 namespace ARICHTools {
39 std::array<uint8_t, 4>({{
'A',
'B',
'C',
'D'}});
51 static constexpr
auto isValidChannel(
const int channel) noexcept ->
bool
56 static auto isValidSector(
const uint8_t sector) noexcept ->
bool
70 ModuleID_t(
const int8_t sector =
'0',
const int channel = 0) noexcept
84 inline auto isValidID() const noexcept ->
bool
86 return ModuleID_t::isValidSector(this->
getSector()) &&
95 inline auto getSector() const noexcept -> int8_t
105 inline auto getChannel() const noexcept -> int8_t
129 rStream <<
id.getSector() <<
static_cast<int>(
id.getChannel());
139 return m_ID == rOther.m_ID;
148 return m_ID != rOther.m_ID;
157 return m_ID < rOther.m_ID;
166 return m_ID <= rOther.m_ID;
175 return m_ID > rOther.m_ID;
184 return m_ID >= rOther.m_ID;
227 namespace PrivateHelperClasses {
233 template <
typename Desired_t>
struct TokenCast;
238 template <>
struct TokenCast<int> {
244 inline auto isValidChar(
const unsigned char character)
const noexcept
247 return std::isdigit(character);
258 inline auto operator()(
const std::string& rToken)
const ->
int
260 return std::stoi(rToken);
270 template <>
struct TokenCast<double> {
276 inline auto isValidChar(
const unsigned char character)
const noexcept
279 return std::isdigit(character) || (
static_cast<unsigned char>(
'.') == character);
290 inline auto operator()(
const std::string& rToken)
const ->
double
292 return std::stod(rToken);
299 template <>
struct TokenCast<ModuleID_t> {
305 inline auto isValidChar(
const unsigned char character)
const noexcept
308 return std::isdigit(character) || ModuleID_t::isValidSector(character);
319 inline auto operator()(
const std::string& rToken)
const ->
ModuleID_t
322 std::find_if(rToken.begin(), rToken.end(),
323 [](
const char c) { return !std::isspace(c); });
324 const auto end = std::find_if(begin, rToken.end(),
325 [](
const char c) { return std::isspace(c); });
327 if ((begin + 1 == end) || !std::all_of(begin, end, [
this](
const char c) {
328 return this->isValidChar(c);
330 throw std::invalid_argument(
"Invalid argiment for module cast, got: '" +
333 const auto chID = std::stoi(std::string(begin + 1, end));
337 throw std::out_of_range(
"Module ID out of range. got: '" + rToken +
"' !");
347 class StringToVector {
366 template <
typename T>
367 static inline auto convert(
const std::string& rLine,
const char delim =
' ')
369 const auto cast = PrivateHelperClasses::TokenCast<T>();
371 if (!std::all_of(rLine.begin(), rLine.end(),
372 [&cast, delim](
const unsigned char c)
374 return std::isdigit(c) || std::isspace(c) ||
375 (c == delim) || cast.isValidChar(c);
377 throw std::runtime_error(
"Detected invalid character in '" + rLine +
380 auto iss = std::istringstream(rLine);
381 auto retval = std::vector<T>();
382 auto token = std::string();
385 while (std::getline(iss, token, delim))
387 retval.emplace_back(cast(token));
388 }
catch (
const std::invalid_argument& rErr)
390 throw std::runtime_error(
"Invalid token, got:'" + token +
"'! " +
392 }
catch (
const std::out_of_range& rErr)
395 throw std::runtime_error(
"Conversion out of range, got: '" + token +
396 "'! " + rErr.what());
412 template <
typename T>
413 static inline auto parse(
const std::string& rLine,
const char delim =
' ')
415 auto out = std::stringstream();
416 auto iss = std::istringstream(rLine);
417 auto token = std::string();
419 if (!std::getline(iss, token, delim))
420 return std::string();
425 StringToVector::expand<T>(out, delim, token);
431 while (std::getline(iss, token, delim))
437 StringToVector::expand<T>(out, delim, token);
439 out << delim << token;
441 }
catch (
const std::invalid_argument& rErr)
443 throw std::runtime_error(
"Invalid token, got:'" + token +
"'! " +
445 }
catch (
const std::out_of_range& rErr)
448 throw std::runtime_error(
"Conversion out of range, got: '" + token +
449 "'! " + rErr.what());
464 template <
typename T>
465 static inline auto expand(std::ostream& rStream,
const char delim,
466 const std::string& rToken) -> std::ostream& {
467 auto itPos = std::search(rToken.begin(), rToken.end(),
469 const auto cast = PrivateHelperClasses::TokenCast<T>();
470 auto lhs = cast(std::string(rToken.begin(), itPos));
472 auto rhs = cast(std::string(itPos, rToken.end()));
475 throw std::runtime_error(
476 "Invalid expansion! lhs ist greater then rhs, got: '" + rToken +
480 for (++lhs; lhs <= rhs; ++lhs)
481 rStream << delim << lhs;
496 auto getDeadCutList(
const char chipID,
const std::string& line)
497 -> std::vector<int> {
498 auto ids = StringToVector::convert<int>(line,
',');
499 for (
auto& rID : ids)
500 rID = ModuleID_t(chipID, rID).getNumbering();
516 std::string& remove_nondigit(std::string& s)
519 s.erase(remove_if(s.begin(), s.end(),
520 [](
const unsigned char& c) { return !std::isdigit(c); }),
532 std::string& remove_chars_if_not(std::string& s,
const std::string& allowed)
534 s.erase(remove_if(s.begin(), s.end(),
535 [&allowed](
const char& c) {
536 return allowed.find(c) == std::string::npos;