-
Notifications
You must be signed in to change notification settings - Fork 15
Open
Description
I'm using vmath with types defined with unchained while working with spatio-temporal data.
Both libs work at compile time, and both roots their functionality on the float type.
I'm dealing with the issue of safely converting DVec/DMat to float based types, like GVec2[Meter] or GVec2[Second] and back to GVec2[float].
A simple cast seems to accomplish the job. Another Nim user helped me by adding when not compiles(T(arr[0])) compile time check alike, but I feel that a solution should exist within vmath.
What's your opinion about adding a safe float-to-floatlike conversion? Do you know a better way to add this functionality into vmath that would span GVec234[T] and GMat234[T]?
import vmath
import unchained
type
GVec234[T] = GVec2[T] | GVec3[T] | GVec4[T]
GMat234[T] = GMat2[T] | GMat3[T] | GMat4[T]
GStuff[T] = GVec234[T] | GMat234[T]
# failing attemps for a shorter solution
# import std/typetraits
# proc asType*[T](arr: GStuff[T], Y: typedesc): GStuff[Y] =
# when not compiles(Y(arr[0])):
# {.error: "Incorrect base type conv".}
# cast[(genericHead(typeof(arr)))[Y]](arr)
# template asType*[T](arr: var GStuff[T], Y: typedesc): var GStuff[Y] =
# when not compiles(T(arr[0])):
# {.error: "Incorrect base type conv".}
# cast[ptr typeof(arr).genericHead()](addr arr)
template asType*[T](arr: GStuff[T], Y: typedesc): GStuff[Y] =
when not compiles(Y(arr[0])):
{.error: "Incorrect base type conv".}
when arr is GVec2[T]:
cast[GVec2[Y]](arr)
elif arr is GVec3[T]:
cast[GVec3[Y]](arr)
elif arr is GVec4[T]:
cast[GVec4[Y]](arr)
elif arr is GMat2[T]:
cast[GMat2[Y]](arr)
elif arr is GMat3[T]:
cast[GMat3[Y]](arr)
else:
cast[GMat4[Y]](arr)
template asType*[T](arr: var GStuff[T], Y: typedesc): var GStuff[Y] =
when not compiles(Y(arr[0])):
{.error: "Incorrect base type conv".}
when arr is GVec2[T]:
cast[ptr GVec2[Y]](addr arr)[]
elif arr is GVec3[T]:
cast[ptr GVec3[Y]](addr arr)[]
elif arr is GVec4[T]:
cast[ptr GVec4[Y]](addr arr)[]
elif arr is GMat2[T]:
cast[ptr GMat2[Y]](addr arr)[]
elif arr is GMat3[T]:
cast[ptr GMat3[Y]](addr arr)[]
else:
cast[ptr GMat4[Y]](addr arr)[]
proc main() =
let p1 = gvec2(1.Meter, 2.Meter)
echo p1
let p2 = p1.asType(float)
echo p2
let p3 = p2.asType(Meter)
echo p3
var p4 = gvec3(1.Second, 2.Second, 3.Second)
echo p4
var p5 = p4.asType(float)
echo p5
var p6 = p5.asType(Second)
echo p6
main()
Thanks
Metadata
Metadata
Assignees
Labels
No labels