Skip to content
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

Implement lenses for std::tuple, std::variant and std::optional #30

Closed
Siapran opened this issue Feb 6, 2020 · 6 comments
Closed

Implement lenses for std::tuple, std::variant and std::optional #30

Siapran opened this issue Feb 6, 2020 · 6 comments

Comments

@Siapran
Copy link
Sponsor Contributor

Siapran commented Feb 6, 2020

It would be nice to access the Nth element of a tuple (std::get), the Nth type of a variant (also std::get), and the only element of a std::optional.

It would also be nice to have cursors return an optional (or throw?) if the underlying part of the view is not present (out of bounds for collections and tuples, bad variant access, nothing in optional).

@arximboldi
Copy link
Owner

Yes, all those lenses and cursors transformations are indeed useful and may be added soon. Thanks! 👍

@Siapran
Copy link
Sponsor Contributor Author

Siapran commented Mar 3, 2020

I need to sort out licensing with my managers but I have a working solution for handling unfocused lenses using optionals: sample unit tests

@Siapran
Copy link
Sponsor Contributor Author

Siapran commented Mar 3, 2020

got an answer on licensing. I'll submit a PR for review soon.

@arximboldi
Copy link
Owner

Awesome! Those tests are looking good, I like that approach. Looking forward to look at that code 🙂

@Siapran
Copy link
Sponsor Contributor Author

Siapran commented Mar 4, 2020

I'm trying to make a smart lens for automatically lifting anything that doesn't handle optionals, but I'm having trouble detecting this properly:

struct functor_wrapper_t {
    template <typename T>
    const_functor<T> operator()(T&& t) const noexcept;
};

template <typename Lens, typename T>
using viewed_t = decltype(
    std::declval<Lens>()(functor_wrapper_t{})(std::declval<T>()).value);

template <typename T>
struct smart_lens<std::optional<T>>
{
    template <typename U>
    static auto make(U &&u) {
        // don't lift lenses that can already handle optionals
        if constexpr (zug::meta::is_detected<viewed_t, U, std::optional<T>>::value) {
            return std::forward<U>(u);
        } else {
            return ::lager::lens::optlift(smart_lens<T>::make(std::forward<U>(u)));
        }
    }
};
TEST_CASE("zooming, unfocused")
{
    state<std::vector<person>> st{{person{{5, 4}, "juanpe"}}};
    auto p  = st[0];
    auto n1 = p[&person::name];
//    auto n2 = p[lens::attr(&person::name)]; // detected as able to handle optional
    auto n3 = p[lens::fallback(person{{1, 1}, "NULL"})];
    auto n4 = p[lens::optlift(lens::attr(&person::name))];
}

I might need some help to finish implementing this...

@arximboldi
Copy link
Owner

You did this, hero! @Siapran

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

No branches or pull requests

2 participants