To make sure the messages in my message-queue are type-safe, I have to record 
the message type in each message.

This is how I went about it:
    
    
    proc idOfType*(T: typedesc): MsgTypeID {.inline.} =
      let tid = 0 # Accesses "type register here" ...
      MsgTypeID(tid)
    
    proc sendMsg*[T](q: QueueID, m: ptr Msg[T]): void {.inline.} =
      let typeidOfT {.global.} = idOfType(T)
      m.mybase.mytypeid = typeidOfT
      fillAndSendMsg[T](q, m, true)
    

It looked like it worked, but then today I realised I was using a single type 
in the test messages, so I added a second type to my test, and then it failed. 
To get it to work again, I have to change the code to this:
    
    
    proc idOfType*(T: typedesc): MsgTypeID {.inline.} =
      let tid = 0 # Accesses "type register here" ...
      MsgTypeID(tid)
    
    proc sendMsg*[T](q: QueueID, m: ptr Msg[T]): void {.inline.} =
      let typeidOfT = idOfType(T)
      m.mybase.mytypeid = typeidOfT
      fillAndSendMsg[T](q, m, true)
    

I was under the impressing that since sendMsg() is generic, the compiler would 
generate one typeidOfT _per type T_. Since my test is now failing with two 
types, I assume the compiler generates a single typeidOfT for all sendMsg() 
"instantiations".

Is there a way to work around that? It's rather expensive to compute the ID of 
a type (it involves locks and creating shared heap objects), so I don't want to 
do that for each message, but rather only once for each type.

I've also tried the following, which doesn't compile:
    
    
    proc sendMsg*[T](q: QueueID, m: ptr Msg[T]): void {.inline.} =
      static:
        let typeidOfT {.global.} = idOfType(T)
      m.mybase.mytypeid = typeidOfT
      fillAndSendMsg[T](q, m, true)
    
    
    
    proc sendMsg*[T](q: QueueID, m: ptr Msg[T]): void {.inline.} =
      static:
        const typeidOfT {.global.} = idOfType(T)
      m.mybase.mytypeid = typeidOfT
      fillAndSendMsg[T](q, m, true)
    

Reply via email to