-// 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.
//
#pragma once
+#include <fmtmacros.hpp>
+
+#include <string_view>
#include <utility>
namespace util {
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_; \
}
}
+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
-// 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.
//
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");
}
}