Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Casting GVec[T]/DMat[T] safely to compatible type #72

Open
arkanoid87 opened this issue Mar 7, 2024 · 0 comments
Open

Casting GVec[T]/DMat[T] safely to compatible type #72

arkanoid87 opened this issue Mar 7, 2024 · 0 comments

Comments

@arkanoid87
Copy link

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

lilkeet added a commit to lilkeet/vmath that referenced this issue Jun 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant