]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
enhance: Add prefix parameter to util::value_or_throw
authorJoel Rosdahl <joel@rosdahl.net>
Thu, 8 Sep 2022 11:26:25 +0000 (13:26 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Wed, 21 Sep 2022 15:06:27 +0000 (17:06 +0200)
src/util/expected.hpp
unittest/test_util_expected.cpp

index 95926f92fccb33e3f751e94fd9b2a9f5bd64a500..e0320da8b1044232bb8a3bf3b8e49018c3c55eb7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2021 Joel Rosdahl and other contributors
+// Copyright (C) 2021-2022 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -18,6 +18,9 @@
 
 #pragma once
 
+#include <fmtmacros.hpp>
+
+#include <string_view>
 #include <utility>
 
 namespace util {
@@ -31,6 +34,12 @@ typename T::value_type value_or_throw(const T& value);
 template<typename E, typename T>
 typename T::value_type value_or_throw(T&& value);
 
+// As above for with `prefix` added to the error message.
+template<typename E, typename T>
+typename T::value_type value_or_throw(const T& value, std::string_view prefix);
+template<typename E, typename T>
+typename T::value_type value_or_throw(T&& value, std::string_view prefix);
+
 #define TRY(x_)                                                                \
   do {                                                                         \
     const auto result = x_;                                                    \
@@ -63,4 +72,26 @@ value_or_throw(T&& value)
   }
 }
 
+template<typename E, typename T>
+inline typename T::value_type
+value_or_throw(const T& value, std::string_view prefix)
+{
+  if (value) {
+    return *value;
+  } else {
+    throw E(FMT("{}{}", prefix, value.error()));
+  }
+}
+
+template<typename E, typename T>
+inline typename T::value_type
+value_or_throw(T&& value, std::string_view prefix)
+{
+  if (value) {
+    return std::move(*value);
+  } else {
+    throw E(FMT("{}{}", prefix, value.error()));
+  }
+}
+
 } // namespace util
index 74f8527034acd825263877aa5beeab2f8f913dbd..723f92efdaafee708831e3e1f28f78bd94d45409 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2021 Joel Rosdahl and other contributors
+// Copyright (C) 2021-2022 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -50,6 +50,37 @@ TEST_CASE("util::value_or_throw")
     const std::string value = "value";
     nonstd::expected<std::unique_ptr<std::string>, const char*> with_value =
       std::make_unique<std::string>(value);
+    const nonstd::expected<int, const char*> without_value =
+      nonstd::make_unexpected("no value");
+
     CHECK(*value_or_throw<TestException>(std::move(with_value)) == value);
+    CHECK_THROWS_WITH(value_or_throw<TestException>(std::move(without_value)),
+                      "no value");
+  }
+
+  SUBCASE("const ref with prefix")
+  {
+    const nonstd::expected<int, const char*> with_value = 42;
+    const nonstd::expected<int, const char*> without_value =
+      nonstd::make_unexpected("no value");
+
+    CHECK(value_or_throw<TestException>(with_value, "prefix: ") == 42);
+    CHECK_THROWS_WITH(value_or_throw<TestException>(without_value, "prefix: "),
+                      "prefix: no value");
+  }
+
+  SUBCASE("move with prefix")
+  {
+    const std::string value = "value";
+    nonstd::expected<std::unique_ptr<std::string>, const char*> with_value =
+      std::make_unique<std::string>(value);
+    const nonstd::expected<int, const char*> without_value =
+      nonstd::make_unexpected("no value");
+
+    CHECK(*value_or_throw<TestException>(std::move(with_value), "prefix: ")
+          == value);
+    CHECK_THROWS_WITH(
+      value_or_throw<TestException>(std::move(without_value), "prefix: "),
+      "prefix: no value");
   }
 }