Created
February 28, 2020 20:18
-
-
Save Siapran/8dfc577e69bc33cdc118ff6aebf18242 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef ANY_LENS_HPP | |
#define ANY_LENS_HPP | |
#include <lager/lenses.hpp> | |
#include <memory> | |
#include <utility> | |
#include <type_traits> | |
namespace detail { | |
template <typename Whole, typename Part> | |
struct ILens { | |
virtual Part view(Whole const &) const = 0; | |
virtual Whole set(Whole const &, Part const &) const = 0; | |
}; | |
template <typename Lens, typename Whole, typename Part> | |
struct LensHolder : public ILens<Whole, Part> { | |
Lens value; | |
template <typename T> | |
LensHolder(T &&other) : value{std::forward<T>(other)} {} | |
Part view(Whole const &w) const override { | |
return ::lager::view(value, w); | |
} | |
Whole set(Whole const &w, Part const &p) const override { | |
return ::lager::set(value, w, p); | |
} | |
}; | |
} | |
template <typename Whole, typename Part> | |
class any_lens { | |
std::shared_ptr<detail::ILens<Whole, Part> const> m_holder; | |
public: | |
any_lens(any_lens const &) = default; | |
any_lens(any_lens &&) = default; | |
any_lens &operator=(any_lens const &) = default; | |
any_lens &operator=(any_lens &&) = default; | |
template <typename Lens, | |
typename std::enable_if< | |
!std::is_same_v<std::decay_t<Lens>, | |
std::decay_t<any_lens>>, int>::type = 0> | |
any_lens(Lens &&lens) : | |
m_holder{new detail::LensHolder<Lens, Whole, Part>{std::forward<Lens>(lens)}} | |
{} | |
auto get() const { | |
return zug::comp([lens = m_holder](auto&& f) { | |
return [&, f](auto&& p) { | |
return f(lens->view(std::forward<decltype(p)>(p)))([&](auto&& x) { | |
return lens->set(std::forward<decltype(p)>(p), | |
std::forward<decltype(x)>(x)); | |
}); | |
}; | |
}); | |
} | |
}; | |
#endif // ANY_LENS_HPP |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment