In the code below, the generic parameter hits the else clause even if it is int. How to make the parameter be late bound in this use case? Making the proc a template did not help.
template IntToStr(t: typedesc): auto =
when t is int:
string
else:
t
proc test[T](t: IntToStr(type(T))) = discard
test[int]("") #type mismatch: got <string> but expected one of: proc (t: int){.noSideEffect, gcsafe.}
Thanks!
A concept would be late bound
type IntToStr[T] = concept type C
when T is int:
C is string
else:
C is T
proc test[T](t: IntToStr[T]) = discard
test[int]("")
test[float](1.0)
No need for complex solution here. Compile time dispatch is easy with Nim's type system :
proc testImpl(t: string) =
echo "string"
proc testImpl(t: int) =
echo "int"
proc testImpl[T](t: T) =
echo "not string|not int"
proc test[T: not int and not string](t: T) =
testImpl[T](t)
proc test[T: int](t: int) =
testImpl(t)
proc test[T: int](t: string) =
var t = $t
testImpl(t)
test[int]("")
test[int](123)
test(0.4)
In this case you can use type aliases.
template IntToStr(t: typedesc): auto =
when t is int:
string
else:
t
type IntToStrTy[T] = IntToStr(T)
proc test[T](t: IntToStrTy[T]) = discard
test[int]("")