Support for std::expected
In C++23, there was a new type std::expected which is essentially Rust's Result.
I've tried to add some functionality to support it, and it seems to work. Should I submit a pull request if this is still relevant?
In C++23, there was a new type
std::expectedwhich is essentially Rust'sResult.I've tried to add some functionality to support it, and it seems to work. Should I submit a pull request if this is still relevant?
Hi @douaumont Thanks for offering to contribution. I'm happy to accept it if you can guard the codes using something like #if __cplusplus >= 202402L (we do not want to break C++17 use cases).
I guess it could be something like this
#include "matchit.h"
#include <expected>
// Generic ok pattern
constexpr auto ok = [](auto const pat) {
using namespace matchit;
return and_(
// Check if it's an expected type with value
pred([](auto&& exp) { return exp.has_value(); }),
// Extract the value
app([](auto&& exp) -> decltype(auto) { return exp.value(); }, pat)
);
};
// Generic err pattern
constexpr auto err = [](auto const pat) {
using namespace matchit;
return and_(
// Check if it's an expected type with error
pred([](auto&& exp) { return !exp.has_value(); }),
// Extract the error
app([](auto&& exp) -> decltype(auto) { return exp.error(); }, pat)
);
};
void process(auto&& exp) { // Works with any std::expected<T, E>
using namespace matchit;
Id<decltype(exp.value())> val;
Id<decltype(exp.error())> err_msg;
match(exp)(
pattern | ok(val) = [&] { std::cout << "Value: " << *val; },
pattern | err(err_msg) = [&] { std::cout << "Error: " << *err_msg; }
);
}
int main() {
process(std::expected<int, std::string>{42}); // Value: 42
process(std::expected<double, int>{std::unexpected{5}}); // Error: 5
return 0;
}