mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-30 18:02:05 +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:
@@ -1882,9 +1882,6 @@ func find*(a: SkipTable, s, sub: string, start: Natural = 0, last = -1): int {.
|
||||
when not (defined(js) or defined(nimdoc) or defined(nimscript)):
|
||||
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>".}
|
||||
|
||||
const hasCStringBuiltin = true
|
||||
else:
|
||||
const hasCStringBuiltin = false
|
||||
@@ -1954,23 +1951,7 @@ func find*(s, sub: string, start: Natural = 0, last = -1): int {.rtl,
|
||||
if sub.len > s.len - start: return -1
|
||||
if sub.len == 1: return find(s, sub[0], start, last)
|
||||
|
||||
template useSkipTable =
|
||||
result = find(initSkipTable(sub), s, sub, start, last)
|
||||
|
||||
when nimvm:
|
||||
useSkipTable()
|
||||
else:
|
||||
when hasCStringBuiltin:
|
||||
if last < 0 and start < s.len:
|
||||
let found = c_strstr(s[start].unsafeAddr, sub)
|
||||
result = if not found.isNil:
|
||||
cast[ByteAddress](found) -% cast[ByteAddress](s.cstring)
|
||||
else:
|
||||
-1
|
||||
else:
|
||||
useSkipTable()
|
||||
else:
|
||||
useSkipTable()
|
||||
result = find(initSkipTable(sub), s, sub, start, last)
|
||||
|
||||
func rfind*(s: string, sub: char, start: Natural = 0, last = -1): int {.rtl,
|
||||
extern: "nsuRFindChar".} =
|
||||
|
||||
@@ -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
|
||||
|
||||
6
tests/stdlib/tstrimpl.nim
Normal file
6
tests/stdlib/tstrimpl.nim
Normal file
@@ -0,0 +1,6 @@
|
||||
import std/private/strimpl
|
||||
|
||||
doAssert find(cstring"Hello Nim", cstring"Nim") == 6
|
||||
doAssert find(cstring"Hello Nim", cstring"N") == 6
|
||||
doAssert find(cstring"Hello Nim", cstring"I") == -1
|
||||
doAssert find(cstring"Hello Nim", cstring"O") == -1
|
||||
@@ -868,5 +868,10 @@ bar
|
||||
doAssert nimIdentNormalize("Foo_bar") == "Foobar"
|
||||
doAssert nimIdentNormalize("_Foo_bar") == "_foobar"
|
||||
|
||||
block: # bug #19500
|
||||
doAssert "abc \0 def".find("def") == 6
|
||||
doAssert "abc \0 def".find('d') == 6
|
||||
|
||||
|
||||
static: main()
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user