#ifndef register_manager_hh_INCLUDED #define register_manager_hh_INCLUDED #include "array_view.hh" #include "exception.hh" #include "utils.hh" #include "unordered_map.hh" #include "string.hh" #include "vector.hh" namespace Kakoune { class Context; class Register { public: virtual ~Register() = default; virtual void set(Context& context, ConstArrayView values) = 0; virtual ConstArrayView get(const Context& context) = 0; }; // static value register, which can be modified // using operator=, so should be user modifiable class StaticRegister : public Register { public: void set(Context&, ConstArrayView values) override { m_content = Vector(values.begin(), values.end()); } ConstArrayView get(const Context&) override { if (m_content.empty()) return ConstArrayView(String::ms_empty); else return ConstArrayView(m_content); } protected: Vector m_content; }; // Dynamic value register, use it's RegisterRetriever // to get it's value when needed. template class DynamicRegister : public StaticRegister { public: DynamicRegister(Getter getter, Setter setter) : m_getter{std::move(getter)}, m_setter{std::move(setter)} {} void set(Context& context, ConstArrayView values) override { m_setter(context, values); } ConstArrayView get(const Context& context) override { m_content = m_getter(context); return StaticRegister::get(context); } private: Getter m_getter; Setter m_setter; }; template std::unique_ptr make_dyn_reg(Func func) { auto setter = [](Context&, ConstArrayView) { throw runtime_error("this register is not assignable"); }; return make_unique>(std::move(func), setter); } template std::unique_ptr make_dyn_reg(Getter getter, Setter setter) { return make_unique>(std::move(getter), std::move(setter)); } class NullRegister : public Register { public: void set(Context&, ConstArrayView) override {} ConstArrayView get(const Context&) override { return ConstArrayView(String::ms_empty); } }; class RegisterManager : public Singleton { public: Register& operator[](StringView reg) const; Register& operator[](Codepoint c) const; void add_register(char c, std::unique_ptr reg); protected: UnorderedMap, MemoryDomain::Registers> m_registers; }; } #endif // register_manager_hh_INCLUDED