#pragma once #include "creeper-qt/utility/wrapper/widget.hh" #include #include namespace creeper { template struct MutableValue final { T value; struct Functor { virtual ~Functor() noexcept = default; virtual void update(const T&) = 0; }; std::unordered_map> callbacks; struct Nothing { }; std::shared_ptr alive = std::make_shared(); MutableValue(const MutableValue&) = delete; MutableValue(MutableValue&&) = delete; template explicit MutableValue(Args&&... args) noexcept requires std::constructible_from : value { std::forward(args)... } { } constexpr auto get() const noexcept -> T { return value; } constexpr operator T() const noexcept { return get(); } template auto set(U&& u) noexcept -> void requires requires(T& t, U&& u) { t = std::forward(u); } { value = std::forward(u); for (const auto& [_, f] : callbacks) f->update(value); } template auto set_silent(U&& u) noexcept -> void requires requires(T& t, U&& u) { t = std::forward(u); } { value = std::forward(u); } template auto operator=(U&& u) noexcept -> void requires requires(T& t, U&& u) { t = std::forward(u); } { set(std::forward(u)); } }; template struct MutableForward final : public P { MutableValue& mutable_value; explicit MutableForward(MutableValue& m) noexcept requires std::constructible_from : mutable_value { m } , P { m.get() } { } template