mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-14 14:03:58 +00:00
Reverse const_strlen() recursion logic
Rather than making the run-time complexity of the algorithm 𝒪(n) where n is the length of the string, make it 𝒪(k) where k is the number of trailing nul bytes. The second parameter `index` with a default non-value is in lieu of a helper function that would have had a name like `count_trailing_nuls()`.
This commit is contained in:
parent
313b70a0c2
commit
071b9b13cd
2 changed files with 10 additions and 5 deletions
11
src/common.h
11
src/common.h
|
@ -731,9 +731,14 @@ static_assert(const_strcmp("a", "aa") < 0, "const_strcmp failure");
|
|||
static_assert(const_strcmp("b", "aa") > 0, "const_strcmp failure");
|
||||
|
||||
/// Compile-time agnostic-size strlen/wcslen implementation. Unicode-unaware.
|
||||
template <typename T>
|
||||
constexpr size_t const_strlen(const T *str) {
|
||||
return *str == static_cast<T>(0) ? 0 : 1 + const_strlen(str + 1);
|
||||
template <typename T, size_t N>
|
||||
constexpr size_t const_strlen(const T(&val)[N], ssize_t index = -1) {
|
||||
// N is the length of the character array, but that includes one **or more** trailing nulls.
|
||||
return index == -1 ? N - const_strlen(val, N - 1)
|
||||
// Prevent an underflow in case the string is comprised of all \0 bytes
|
||||
: index == 0 ? 1
|
||||
// Keep back-tracking until a non-null byte is found
|
||||
: (val[index] == static_cast<T>(0) ? 1 + const_strlen(val, index - 1) : 0);
|
||||
}
|
||||
static_assert(const_strlen("") == 0, "const_strlen failure");
|
||||
static_assert(const_strlen("hello") == 5, "const_strlen failure");
|
||||
|
|
|
@ -370,7 +370,7 @@ static size_t offset_of_next_item_fish_2_0(const history_file_contents_t &conten
|
|||
|
||||
// Hackish: fish 1.x rewriting a fish 2.0 history file can produce lines with lots of
|
||||
// leading "- cmd: - cmd: - cmd:". Trim all but one leading "- cmd:".
|
||||
constexpr const char *double_cmd = "- cmd: - cmd: ";
|
||||
constexpr const char double_cmd[] = "- cmd: - cmd: ";
|
||||
constexpr const size_t double_cmd_len = const_strlen(double_cmd);
|
||||
while (static_cast<size_t>(a_newline - line_start) > double_cmd_len &&
|
||||
!std::memcmp(line_start, double_cmd, double_cmd_len)) {
|
||||
|
@ -380,7 +380,7 @@ static size_t offset_of_next_item_fish_2_0(const history_file_contents_t &conten
|
|||
|
||||
// Hackish: fish 1.x rewriting a fish 2.0 history file can produce commands like "when:
|
||||
// 123456". Ignore those.
|
||||
constexpr const char *cmd_when = "- cmd: when:";
|
||||
constexpr const char cmd_when[] = "- cmd: when:";
|
||||
constexpr const size_t cmd_when_len = const_strlen(cmd_when);
|
||||
if (static_cast<size_t>(a_newline - line_start) >= cmd_when_len &&
|
||||
!std::memcmp(line_start, cmd_when, cmd_when_len)) {
|
||||
|
|
Loading…
Reference in a new issue