Just to give a flavor for the curious, it could look roughly like this in Nim:
import core/macros, std/bitops
macro makeSharFind(id; n: int) =
let (x, e, n) = (ident("x"), ident("e"), n.intVal)
let k = fastLog2(n); let k2 = 1 shl k
result = quote do:
proc `id`[T](`x`: openArray[T], `e`: T): int =
result = if `x`[`k2`] <= `e`: `n` - `k2` else: 0
for p in countdown(k - 1, 0):
let p2 = 1 shl p
result[^1].add quote do:
if `x`[result + `p2`] <= `e`: result += `p2`
result[^1].add quote do:
if `x`[result] != `e`: result = -1
const x = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
makeSharFind(sharFind, x.len) # Non-const needs a fallback
for i in -1..x.len: echo x.sharFind(i*10) # < x[0], >x[^1]
for i in -1..<x.len: echo x.sharFind(i*10+5) # inside miss
with just minimal testing at the end (so, yeah, maybe some bugs). Output of the above for me (pasted into 2 cols) is the expected:
Just to give a flavor for the curious, it could look roughly like this in Nim:
with just minimal testing at the end (so, yeah, maybe some bugs). Output of the above for me (pasted into 2 cols) is the expected:
and you can run
nim c --expandMacro=makeSharFind
to see generated code.