From: Joel Rosdahl Date: Thu, 8 Sep 2022 11:53:58 +0000 (+0200) Subject: enhance: Add util::throw_on_error functions X-Git-Tag: v4.7~64 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4da534ce0f1d2a89f786d4abdb1aa86e3d68e9ba;p=thirdparty%2Fccache.git enhance: Add util::throw_on_error functions --- diff --git a/src/util/expected.hpp b/src/util/expected.hpp index e0320da8b..03bebd5a4 100644 --- a/src/util/expected.hpp +++ b/src/util/expected.hpp @@ -34,12 +34,20 @@ typename T::value_type value_or_throw(const T& value); template typename T::value_type value_or_throw(T&& value); -// As above for with `prefix` added to the error message. +// Like above for with `prefix` added to the error message. template typename T::value_type value_or_throw(const T& value, std::string_view prefix); template typename T::value_type value_or_throw(T&& value, std::string_view prefix); +// Throw an exception of type `E` with a `T::error_type` as the argument if +// `value` is false. +template void throw_on_error(const T& value); + +// Like above for with `prefix` added to the error message. +template +void throw_on_error(const T& value, std::string_view prefix); + #define TRY(x_) \ do { \ const auto result = x_; \ @@ -94,4 +102,23 @@ value_or_throw(T&& value, std::string_view prefix) } } +template +inline void +throw_on_error(const T& value) +{ + if (!value) { + throw E(value.error()); + } +} + +// Like above for with `prefix` added to the error message. +template +inline void +throw_on_error(const T& value, std::string_view prefix) +{ + if (!value) { + throw E(FMT("{}{}", prefix, value.error())); + } +} + } // namespace util diff --git a/unittest/test_util_expected.cpp b/unittest/test_util_expected.cpp index 723f92efd..585b1ab6a 100644 --- a/unittest/test_util_expected.cpp +++ b/unittest/test_util_expected.cpp @@ -33,16 +33,17 @@ class TestException : public std::runtime_error TEST_CASE("util::value_or_throw") { + using util::throw_on_error; using util::value_or_throw; SUBCASE("const ref") { const nonstd::expected with_value = 42; - const nonstd::expected without_value = + const nonstd::expected with_error = nonstd::make_unexpected("no value"); CHECK(value_or_throw(with_value) == 42); - CHECK_THROWS_WITH(value_or_throw(without_value), "no value"); + CHECK_THROWS_WITH(value_or_throw(with_error), "no value"); } SUBCASE("move") @@ -50,22 +51,22 @@ TEST_CASE("util::value_or_throw") const std::string value = "value"; nonstd::expected, const char*> with_value = std::make_unique(value); - const nonstd::expected without_value = + const nonstd::expected with_error = nonstd::make_unexpected("no value"); CHECK(*value_or_throw(std::move(with_value)) == value); - CHECK_THROWS_WITH(value_or_throw(std::move(without_value)), + CHECK_THROWS_WITH(value_or_throw(std::move(with_error)), "no value"); } SUBCASE("const ref with prefix") { const nonstd::expected with_value = 42; - const nonstd::expected without_value = + const nonstd::expected with_error = nonstd::make_unexpected("no value"); CHECK(value_or_throw(with_value, "prefix: ") == 42); - CHECK_THROWS_WITH(value_or_throw(without_value, "prefix: "), + CHECK_THROWS_WITH(value_or_throw(with_error, "prefix: "), "prefix: no value"); } @@ -74,13 +75,34 @@ TEST_CASE("util::value_or_throw") const std::string value = "value"; nonstd::expected, const char*> with_value = std::make_unique(value); - const nonstd::expected without_value = + const nonstd::expected with_error = nonstd::make_unexpected("no value"); CHECK(*value_or_throw(std::move(with_value), "prefix: ") == value); CHECK_THROWS_WITH( - value_or_throw(std::move(without_value), "prefix: "), + value_or_throw(std::move(with_error), "prefix: "), "prefix: no value"); } + + SUBCASE("void T::value_type") + { + const nonstd::expected without_error; + const nonstd::expected with_error = + nonstd::make_unexpected("no value"); + + CHECK_NOTHROW(throw_on_error(without_error)); + CHECK_THROWS_WITH(throw_on_error(with_error), "no value"); + } + + SUBCASE("void T::value_type with prefix") + { + const nonstd::expected without_error; + const nonstd::expected with_error = + nonstd::make_unexpected("no value"); + + CHECK_NOTHROW(throw_on_error(without_error, "prefix: ")); + CHECK_THROWS_WITH(throw_on_error(with_error, "prefix: "), + "prefix: no value"); + } }