From 831e9082d7eff41644104e493f00bacd8a8952ea Mon Sep 17 00:00:00 2001 From: Aaron Gyes Date: Fri, 1 Oct 2021 03:38:06 -0700 Subject: [PATCH] enum_map stuff to enum_map.h --- src/builtin_history.cpp | 1 + src/builtin_status.cpp | 1 + src/common.h | 43 ---------------------------------- src/enum_map.h | 51 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 43 deletions(-) create mode 100644 src/enum_map.h diff --git a/src/builtin_history.cpp b/src/builtin_history.cpp index 0c9b49461..7f38dd5b0 100644 --- a/src/builtin_history.cpp +++ b/src/builtin_history.cpp @@ -12,6 +12,7 @@ #include "builtin.h" #include "common.h" +#include "enum_map.h" #include "fallback.h" // IWYU pragma: keep #include "history.h" #include "io.h" diff --git a/src/builtin_status.cpp b/src/builtin_status.cpp index f007ed4fd..d6a4c7dc3 100644 --- a/src/builtin_status.cpp +++ b/src/builtin_status.cpp @@ -9,6 +9,7 @@ #include "builtin.h" #include "common.h" +#include "enum_map.h" #include "fallback.h" // IWYU pragma: keep #include "future_feature_flags.h" #include "io.h" diff --git a/src/common.h b/src/common.h index cab391880..c062f511e 100644 --- a/src/common.h +++ b/src/common.h @@ -579,49 +579,6 @@ long convert_digit(wchar_t d, int base); // Return true if the character is in a range reserved for fish's private use. bool fish_reserved_codepoint(wchar_t c); -/// Used for constructing mappings between enums and strings. The resulting array must be sorted -/// according to the `str` member since str_to_enum() does a binary search. Also the last entry must -/// have NULL for the `str` member and the default value for `val` to be returned if the string -/// isn't found. -template -struct enum_map { - T val; - const wchar_t *const str; -}; - -/// Given a string return the matching enum. Return the sentinel enum if no match is made. The map -/// must be sorted by the `str` member. A binary search is twice as fast as a linear search with 16 -/// elements in the map. -template -static T str_to_enum(const wchar_t *name, const enum_map map[], int len) { - // Ignore the sentinel value when searching as it is the "not found" value. - size_t left = 0, right = len - 1; - - while (left < right) { - size_t mid = left + (right - left) / 2; - int cmp = std::wcscmp(name, map[mid].str); - if (cmp < 0) { - right = mid; // name was smaller than mid - } else if (cmp > 0) { - left = mid + 1; // name was larger than mid - } else { - return map[mid].val; // found it - } - } - return map[len - 1].val; // return the sentinel value -} - -/// Given an enum return the matching string. -template -static const wchar_t *enum_to_str(T enum_val, const enum_map map[]) { - for (const enum_map *entry = map; entry->str; entry++) { - if (enum_val == entry->val) { - return entry->str; - } - } - return nullptr; -}; - void redirect_tty_output(); std::string get_path_to_tmp_dir(); diff --git a/src/enum_map.h b/src/enum_map.h new file mode 100644 index 000000000..dc35d2327 --- /dev/null +++ b/src/enum_map.h @@ -0,0 +1,51 @@ +#ifndef FISH_ENUM_MAP_H +#define FISH_ENUM_MAP_H + +#include "config.h" // IWYU pragma: keep + +#include + +/// Used for constructing mappings between enums and strings. The resulting array must be sorted +/// according to the `str` member since str_to_enum() does a binary search. Also the last entry must +/// have NULL for the `str` member and the default value for `val` to be returned if the string +/// isn't found. +template +struct enum_map { + T val; + const wchar_t *const str; +}; + +/// Given a string return the matching enum. Return the sentinel enum if no match is made. The map +/// must be sorted by the `str` member. A binary search is twice as fast as a linear search with 16 +/// elements in the map. +template +T str_to_enum(const wchar_t *name, const enum_map map[], int len) { + // Ignore the sentinel value when searching as it is the "not found" value. + size_t left = 0, right = len - 1; + + while (left < right) { + size_t mid = left + (right - left) / 2; + int cmp = std::wcscmp(name, map[mid].str); + if (cmp < 0) { + right = mid; // name was smaller than mid + } else if (cmp > 0) { + left = mid + 1; // name was larger than mid + } else { + return map[mid].val; // found it + } + } + return map[len - 1].val; // return the sentinel value +} + +/// Given an enum return the matching string. +template +const wchar_t *enum_to_str(T enum_val, const enum_map map[]) { + for (const enum_map *entry = map; entry->str; entry++) { + if (enum_val == entry->val) { + return entry->str; + } + } + return nullptr; +}; + +#endif