#include #include #include #include #include #include struct ParseError : std::runtime_error { using std::runtime_error::runtime_error; }; int parse_cents(std::string_view text) { if (text.empty()) throw ParseError("empty amount"); int cents = 0; const char* end = text.data() + text.size(); const auto result = std::from_chars(text.data(), end, cents); if (result.ec != std::errc{} || result.ptr != end || cents < 0) throw ParseError("invalid amount"); return cents; } int preserve_error(std::string_view text) { try { return parse_cents(text); } catch (const std::exception&) { throw; } } enum class Status { accepted, bad_amount }; struct Receipt { Status status; std::optional cents; }; Receipt submit(std::string_view text) { try { return {Status::accepted, parse_cents(text)}; } catch (const ParseError&) { return {Status::bad_amount, std::nullopt}; } } int main() { const auto good = submit("1250"); assert(good.status == Status::accepted && good.cents == 1250); const auto bad = submit("12x"); assert(bad.status == Status::bad_amount && !bad.cents); assert(!submit("9999999999999999999999999999999999999999").cents); bool preserved = false; try { (void)preserve_error(""); } catch (const ParseError&) { preserved = true; } assert(preserved); }