Skip to content

Implicit Conversion for fine::Ok and fine::Error #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 14, 2025

Conversation

brodeuralexis
Copy link
Contributor

@brodeuralexis brodeuralexis commented Aug 13, 2025

This rework ensures that fine::Ok and fine::Error can correctly convert when used in conjunction with container types like std::variant.

This is an alternative to #12. Instead of exposing a result type, we ensure that conversions when fine::Ok and fine::Error with std::variant work as expected.

The downside to this implementation is the need to go through 2 factory functions, fine::ok and fine::error, to construct these correctly. I believe this problem could be solved, like CTAD is applicable to tuples, but it would require a lot more template metaprogramming to get everything working correctly.

This rework ensures that `fine::Ok` and `fine::Error` can correctly
convert when used in conjunction with container types like
`std::variant`.

The downside to this approach, as implemented, is the need to go through
2 factory functions, `fine::ok` and `fine::error`, to construct these.
Class Template Argument Deduction allows class templates to be inferred
from constructor arguments, which removes the need for `fine::ok` and
`fine::error` as special factory functions.
@brodeuralexis brodeuralexis changed the title Rework fine::Ok and fine::Error Implicit Conversion for fine::Ok and fine::Error Aug 14, 2025
Copy link
Member

@jonatanklosko jonatanklosko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, I dropped minor notes :)

std::variant<fine::Ok<int64_t>, fine::Error<std::string>> find_meaning(ErlNifEnv *env) {
if (...) {
return fine::Error<std::string>("something went wrong");
std::variant<fine::Ok<int64_t, int64_t>, fine::Error<std::string>> divmod(ErlNifEnv *env, int64_t a, int64_t b) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

Comment on lines 150 to 151
template <typename = std::enable_if_t<std::is_default_constructible_v<Items>>>
Ok() : m_items() {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We know that std::tuple<>() is constructible, so we don't need this conditional?

Suggested change
template <typename = std::enable_if_t<std::is_default_constructible_v<Items>>>
Ok() : m_items() {}
Ok() : m_items() {}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A remnant from trying to understand and make the template code works. I though I still needed it.
It is analogous to Ok<Args...>::Ok(Args...) with an empty parameter pack.

Also, keeping this would enable constructing like so:

return fine::Ok<std::string> {};

Which I don't think is wanted.

@jonatanklosko jonatanklosko merged commit 4f2a521 into elixir-nx:main Aug 14, 2025
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants