From b4cc30530d4a7bb8995305fe0a49526ae43d1f00 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Tue, 31 May 2022 16:42:36 -0700 Subject: [PATCH] Use a singly-linked list for completion options When the user adds a completion for a command, we push it to the front of the completion list so it appears first; for that reason we don't want to use a vector. However we can do better than std::list; try using std::forward_list which is singly linked. No functional change here (but we will see if this breaks any old platforms in which case it's fine to revert this). --- src/complete.cpp | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/src/complete.cpp b/src/complete.cpp index f2ec6b123..ec0045e0a 100644 --- a/src/complete.cpp +++ b/src/complete.cpp @@ -16,9 +16,9 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -124,7 +124,7 @@ struct complete_entry_opt_t { static relaxed_atomic_t k_complete_order{0}; /// Struct describing a command completion. -using option_list_t = std::list; +using option_list_t = std::forward_list; class completion_entry_t { public: /// List of all options. @@ -137,28 +137,21 @@ class completion_entry_t { /// Getters for option list. const option_list_t &get_options() const { return options; } - /// Adds or removes an option. + /// Adds an option. void add_option(const complete_entry_opt_t &opt) { options.push_front(opt); } - bool remove_option(const wcstring &option, complete_option_type_t type); + + /// Remove all completion options in the specified entry that match the specified short / long + /// option strings. Returns true if it is now empty and should be deleted, false if it's not + /// empty. + bool remove_option(const wcstring &option, complete_option_type_t type) { + this->options.remove_if([&](const complete_entry_opt_t &opt) { + return opt.option == option && opt.type == type; + }); + return this->options.empty(); + } completion_entry_t() : order(++k_complete_order) {} }; - -/// Remove all completion options in the specified entry that match the specified short / long -/// option strings. Returns true if it is now empty and should be deleted, false if it's not empty. -/// Must be called while locked. -bool completion_entry_t::remove_option(const wcstring &option, complete_option_type_t type) { - auto iter = this->options.begin(); - while (iter != this->options.end()) { - if (iter->option == option && iter->type == type) { - iter = this->options.erase(iter); - } else { - // Just go to the next one. - ++iter; - } - } - return this->options.empty(); -} } // namespace /// Set of all completion entries. Keyed by the command name, and whether it is a path.