|
|
@@ -3,7 +3,7 @@
|
|
|
#include <type_traits>
|
|
|
|
|
|
#ifdef __cpp_lib_expected
|
|
|
-#if __cpp_lib_expected >= 202202L
|
|
|
+#if __cpp_lib_expected >= 202211L
|
|
|
#include <expected>
|
|
|
|
|
|
namespace jvalidate::detail {
|
|
|
@@ -171,6 +171,54 @@ public:
|
|
|
constexpr E & error() & noexcept { return *std::get_if<1>(&value_); }
|
|
|
constexpr E && error() && noexcept { return std::move(*std::get_if<1>(&value_)); }
|
|
|
|
|
|
+ template <typename F> constexpr auto transform(F && f) & {
|
|
|
+ using G = std::invoke_result_t<F, value_type &>;
|
|
|
+ if (has_value()) {
|
|
|
+ return expected<G, error_type>(std::forward<F>(f)(**this));
|
|
|
+ }
|
|
|
+ return expected<G, error_type>(unexpect, error());
|
|
|
+ }
|
|
|
+
|
|
|
+ template <typename F> constexpr auto transform(F && f) const & {
|
|
|
+ using G = std::invoke_result_t<F, value_type const &>;
|
|
|
+ if (has_value()) {
|
|
|
+ return expected<G, error_type>(std::forward<F>(f)(**this));
|
|
|
+ }
|
|
|
+ return expected<G, error_type>(unexpect, error());
|
|
|
+ }
|
|
|
+
|
|
|
+ template <typename F> constexpr auto transform(F && f) && {
|
|
|
+ using G = std::invoke_result_t<F, value_type>;
|
|
|
+ if (has_value()) {
|
|
|
+ return expected<G, error_type>(std::forward<F>(f)(*std::move(*this)));
|
|
|
+ }
|
|
|
+ return expected<G, error_type>(unexpect, std::move(*this).error());
|
|
|
+ }
|
|
|
+
|
|
|
+ template <typename F> constexpr auto transform_error(F && f) & {
|
|
|
+ using G = std::invoke_result_t<F, E &>;
|
|
|
+ if (has_value()) {
|
|
|
+ return expected<value_type, G>(**this);
|
|
|
+ }
|
|
|
+ return expected<value_type, G>(unexpect, std::forward<F>(f)(error()));
|
|
|
+ }
|
|
|
+
|
|
|
+ template <typename F> constexpr auto transform_error(F && f) const & {
|
|
|
+ using G = std::invoke_result_t<F, E const &>;
|
|
|
+ if (has_value()) {
|
|
|
+ return expected<value_type, G>(**this);
|
|
|
+ }
|
|
|
+ return expected<value_type, G>(unexpect, std::forward<F>(f)(error()));
|
|
|
+ }
|
|
|
+
|
|
|
+ template <typename F> constexpr auto transform_error(F && f) && {
|
|
|
+ using G = std::invoke_result_t<F, E>;
|
|
|
+ if (has_value()) {
|
|
|
+ return expected<value_type, G>(*std::move(*this));
|
|
|
+ }
|
|
|
+ return expected<value_type, G>(unexpect, std::forward<F>(f)(std::move(*this).error()));
|
|
|
+ }
|
|
|
+
|
|
|
private:
|
|
|
std::variant<T, E> value_;
|
|
|
};
|
|
|
@@ -241,8 +289,60 @@ public:
|
|
|
constexpr E & error() & noexcept { return *value_; }
|
|
|
constexpr E && error() && noexcept { return std::move(*value_); }
|
|
|
|
|
|
+ template <typename F> constexpr auto transform(F && f) & {
|
|
|
+ using G = std::invoke_result_t<F>;
|
|
|
+ if (has_value()) {
|
|
|
+ return expected<G, error_type>(std::forward<F>(f)());
|
|
|
+ }
|
|
|
+ return expected<G, error_type>(unexpect, error());
|
|
|
+ }
|
|
|
+
|
|
|
+ template <typename F> constexpr auto transform(F && f) const & {
|
|
|
+ using G = std::invoke_result_t<F>;
|
|
|
+ if (has_value()) {
|
|
|
+ return expected<G, error_type>(std::forward<F>(f)());
|
|
|
+ }
|
|
|
+ return expected<G, error_type>(unexpect, error());
|
|
|
+ }
|
|
|
+
|
|
|
+ template <typename F> constexpr auto transform(F && f) && {
|
|
|
+ using G = std::invoke_result_t<F>;
|
|
|
+ if (has_value()) {
|
|
|
+ return expected<G, error_type>(std::forward<F>(f)());
|
|
|
+ }
|
|
|
+ return expected<G, error_type>(unexpect, std::move(*this).error());
|
|
|
+ }
|
|
|
+
|
|
|
+ template <typename F> constexpr auto transform_error(F && f) & {
|
|
|
+ using G = std::invoke_result_t<F, E &>;
|
|
|
+ if (has_value()) {
|
|
|
+ return expected<value_type, G>(**this);
|
|
|
+ }
|
|
|
+ return expected<value_type, G>(unexpect, std::forward<F>(f)(error()));
|
|
|
+ }
|
|
|
+
|
|
|
+ template <typename F> constexpr auto transform_error(F && f) const & {
|
|
|
+ using G = std::invoke_result_t<F, E const &>;
|
|
|
+ if (has_value()) {
|
|
|
+ return expected<value_type, G>(**this);
|
|
|
+ }
|
|
|
+ return expected<value_type, G>(unexpect, std::forward<F>(f)(error()));
|
|
|
+ }
|
|
|
+
|
|
|
+ template <typename F> constexpr auto transform_error(F && f) && {
|
|
|
+ using G = std::invoke_result_t<F, E>;
|
|
|
+ if (has_value()) {
|
|
|
+ return expected<value_type, G>(*std::move(*this));
|
|
|
+ }
|
|
|
+ return expected<value_type, G>(unexpect, std::forward<F>(f)(std::move(*this).error()));
|
|
|
+ }
|
|
|
+
|
|
|
private:
|
|
|
std::optional<E> value_;
|
|
|
};
|
|
|
}
|
|
|
#endif
|
|
|
+
|
|
|
+namespace jvalidate::detail {
|
|
|
+inline std::string to_message(std::errc ec) { return std::make_error_code(ec).message(); }
|
|
|
+}
|