Rewrite OptionManager::flatten_options to use ranges

Avoid accumulating the flattened options into a vector, generate
a lazy range that will give the proper list.
This commit is contained in:
Maxime Coste 2018-02-20 23:32:51 +11:00
parent 6d111d4bd7
commit 69a0ad09b4
2 changed files with 14 additions and 17 deletions

View File

@ -87,20 +87,6 @@ void OptionManager::unset_option(StringView name)
} }
} }
OptionManager::OptionList OptionManager::flatten_options() const
{
OptionList res = m_parent ? m_parent->flatten_options() : OptionList{};
for (auto& option : m_options)
{
auto it = find_if(res, [&](const Option* opt) { return opt->name() == option.key; });
if (it != res.end())
*it = option.value.get();
else
res.emplace_back(option.value.get());
}
return res;
}
void OptionManager::on_option_changed(const Option& option) void OptionManager::on_option_changed(const Option& option)
{ {
// if parent option changed, but we overrided it, it's like nothing happened // if parent option changed, but we overrided it, it's like nothing happened

View File

@ -90,8 +90,18 @@ public:
void unset_option(StringView name); void unset_option(StringView name);
using OptionList = Vector<const Option*>; auto flatten_options() const
OptionList flatten_options() const; {
auto merge = [](auto&& first, const OptionMap& second) {
return concatenated(std::forward<decltype(first)>(first)
| filter([&second](auto& i) { return not second.contains(i.key); }),
second);
};
static const OptionMap empty;
auto& parent = m_parent ? m_parent->m_options : empty;
auto& grand_parent = (m_parent and m_parent->m_parent) ? m_parent->m_parent->m_options : empty;
return merge(merge(grand_parent, parent), m_options) | transform(std::mem_fn(&OptionMap::Item::value));
}
void register_watcher(OptionManagerWatcher& watcher) const; void register_watcher(OptionManagerWatcher& watcher) const;
void unregister_watcher(OptionManagerWatcher& watcher) const; void unregister_watcher(OptionManagerWatcher& watcher) const;
@ -103,8 +113,9 @@ private:
// the only one allowed to construct a root option manager // the only one allowed to construct a root option manager
friend class Scope; friend class Scope;
friend class OptionsRegistry; friend class OptionsRegistry;
using OptionMap = HashMap<StringView, std::unique_ptr<Option>, MemoryDomain::Options>;
HashMap<StringView, std::unique_ptr<Option>, MemoryDomain::Options> m_options; OptionMap m_options;
OptionManager* m_parent; OptionManager* m_parent;
mutable Vector<OptionManagerWatcher*, MemoryDomain::Options> m_watchers; mutable Vector<OptionManagerWatcher*, MemoryDomain::Options> m_watchers;