AK: Allow customising Trie's underlying map type

This makes it possible to use an ordered map and keep the insertion
order intact.
This commit is contained in:
Ali Mohammad Pur 2023-07-28 20:52:34 +03:30 committed by Andreas Kling
parent 07e4358c63
commit 7a471b7cf5
Notes: sideshowbarker 2024-07-16 18:06:41 +09:00

View File

@ -26,7 +26,7 @@ struct SubstituteIfVoid<void, Default> {
using Type = Default; using Type = Default;
}; };
template<typename DeclaredBaseType, typename DefaultBaseType, typename ValueType, typename MetadataT, typename ValueTraits> template<typename DeclaredBaseType, typename DefaultBaseType, typename ValueType, typename MetadataT, typename ValueTraits, template<typename, typename, typename> typename MapType>
class Trie { class Trie {
using BaseType = typename SubstituteIfVoid<DeclaredBaseType, DefaultBaseType>::Type; using BaseType = typename SubstituteIfVoid<DeclaredBaseType, DefaultBaseType>::Type;
@ -69,6 +69,8 @@ public:
return const_cast<Trie*>(this)->traverse_until_last_accessible_node(it, end); return const_cast<Trie*>(this)->traverse_until_last_accessible_node(it, end);
} }
bool has_metadata() const { return m_metadata.has_value(); }
Optional<MetadataType> metadata() const Optional<MetadataType> metadata() const
requires(!IsNullPointer<MetadataType>) requires(!IsNullPointer<MetadataType>)
{ {
@ -166,16 +168,16 @@ public:
return insert(it, end); return insert(it, end);
} }
HashMap<ValueType, NonnullOwnPtr<Trie>, ValueTraits>& children() { return m_children; } MapType<ValueType, NonnullOwnPtr<Trie>, ValueTraits>& children() { return m_children; }
HashMap<ValueType, NonnullOwnPtr<Trie>, ValueTraits> const& children() const { return m_children; } MapType<ValueType, NonnullOwnPtr<Trie>, ValueTraits> const& children() const { return m_children; }
template<typename Fn> template<typename Fn>
ErrorOr<void> for_each_node_in_tree_order(Fn callback) const ErrorOr<void> for_each_node_in_tree_order(Fn callback) const
{ {
struct State { struct State {
bool did_generate_root { false }; bool did_generate_root { false };
typename HashMap<ValueType, NonnullOwnPtr<Trie>, ValueTraits>::ConstIteratorType it; typename MapType<ValueType, NonnullOwnPtr<Trie>, ValueTraits>::ConstIteratorType it;
typename HashMap<ValueType, NonnullOwnPtr<Trie>, ValueTraits>::ConstIteratorType end; typename MapType<ValueType, NonnullOwnPtr<Trie>, ValueTraits>::ConstIteratorType end;
}; };
Vector<State> state; Vector<State> state;
TRY(state.try_empend(false, m_children.begin(), m_children.end())); TRY(state.try_empend(false, m_children.begin(), m_children.end()));
@ -265,20 +267,23 @@ private:
ValueType m_value; ValueType m_value;
Optional<MetadataType> m_metadata; Optional<MetadataType> m_metadata;
HashMap<ValueType, NonnullOwnPtr<Trie>, ValueTraits> m_children; MapType<ValueType, NonnullOwnPtr<Trie>, ValueTraits> m_children;
}; };
template<typename BaseType, typename DefaultBaseType, typename ValueType, typename ValueTraits> template<typename BaseType, typename DefaultBaseType, typename ValueType, typename ValueTraits, template<typename, typename, typename> typename MapType>
class Trie<BaseType, DefaultBaseType, ValueType, void, ValueTraits> : public Trie<BaseType, DefaultBaseType, ValueType, decltype(nullptr), ValueTraits> { class Trie<BaseType, DefaultBaseType, ValueType, void, ValueTraits, MapType> : public Trie<BaseType, DefaultBaseType, ValueType, decltype(nullptr), ValueTraits, MapType> {
using Trie<BaseType, DefaultBaseType, ValueType, decltype(nullptr), ValueTraits>::Trie; using Trie<BaseType, DefaultBaseType, ValueType, decltype(nullptr), ValueTraits, MapType>::Trie;
}; };
template<typename K, typename V, typename T>
using HashMapForTrie = HashMap<K, V, T>;
} }
template<typename ValueType, typename MetadataT = void, typename ValueTraits = Traits<ValueType>, typename BaseT = void> template<typename ValueType, typename MetadataT = void, typename ValueTraits = Traits<ValueType>, typename BaseT = void, template<typename, typename, typename> typename MapType = Detail::HashMapForTrie>
class Trie : public Detail::Trie<BaseT, Trie<ValueType, MetadataT, ValueTraits>, ValueType, MetadataT, ValueTraits> { class Trie : public Detail::Trie<BaseT, Trie<ValueType, MetadataT, ValueTraits, void, MapType>, ValueType, MetadataT, ValueTraits, MapType> {
public: public:
using DetailTrie = Detail::Trie<BaseT, Trie<ValueType, MetadataT, ValueTraits>, ValueType, MetadataT, ValueTraits>; using DetailTrie = Detail::Trie<BaseT, Trie<ValueType, MetadataT, ValueTraits, void, MapType>, ValueType, MetadataT, ValueTraits, MapType>;
using MetadataType = typename DetailTrie::MetadataType; using MetadataType = typename DetailTrie::MetadataType;
Trie(ValueType value, MetadataType metadata) Trie(ValueType value, MetadataType metadata)