mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 05:50:30 +00:00
* remove find optimization close #19500 * save find to std * add simple tests * Apply suggestions from code review Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com> Co-authored-by: sandytypical <43030857+xflywind@users.noreply.github.com> Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com>
This commit is contained in:
@@ -74,3 +74,40 @@ template endsWithImpl*[T: string | cstring](s, suffix: T) =
|
||||
|
||||
func cmpNimIdentifier*[T: string | cstring](a, b: T): int =
|
||||
cmpIgnoreStyleImpl(a, b, true)
|
||||
|
||||
func c_memchr(cstr: pointer, c: char, n: csize_t): pointer {.
|
||||
importc: "memchr", header: "<string.h>".}
|
||||
func c_strstr(haystack, needle: cstring): cstring {.
|
||||
importc: "strstr", header: "<string.h>".}
|
||||
|
||||
|
||||
func find*(s: cstring, sub: char, start: Natural = 0, last = 0): int =
|
||||
## Searches for `sub` in `s` inside the range `start..last` (both ends included).
|
||||
## If `last` is unspecified, it defaults to `s.high` (the last element).
|
||||
##
|
||||
## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned.
|
||||
## Otherwise the index returned is relative to `s[0]`, not `start`.
|
||||
## Use `s[start..last].rfind` for a `start`-origin index.
|
||||
let last = if last == 0: s.high else: last
|
||||
let L = last-start+1
|
||||
if L > 0:
|
||||
let found = c_memchr(s[start].unsafeAddr, sub, cast[csize_t](L))
|
||||
if not found.isNil:
|
||||
return cast[ByteAddress](found) -% cast[ByteAddress](s)
|
||||
return -1
|
||||
|
||||
func find*(s, sub: cstring, start: Natural = 0, last = 0): int =
|
||||
## Searches for `sub` in `s` inside the range `start..last` (both ends included).
|
||||
## If `last` is unspecified, it defaults to `s.high` (the last element).
|
||||
##
|
||||
## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned.
|
||||
## Otherwise the index returned is relative to `s[0]`, not `start`.
|
||||
## Use `s[start..last].find` for a `start`-origin index.
|
||||
if sub.len > s.len - start: return -1
|
||||
if sub.len == 1: return find(s, sub[0], start, last)
|
||||
if last == 0 and s.len > start:
|
||||
let found = c_strstr(s[start].unsafeAddr, sub)
|
||||
if not found.isNil:
|
||||
result = cast[ByteAddress](found) -% cast[ByteAddress](s)
|
||||
else:
|
||||
result = -1
|
||||
|
||||
Reference in New Issue
Block a user