tconverter_unique_ptr.nim 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. discard """
  2. targets: "c cpp"
  3. output: ""
  4. """
  5. ## Bugs 9698 and 9699
  6. type
  7. UniquePtr*[T] = object
  8. ## non copyable pointer to object T, exclusive ownership of the object is assumed
  9. val: ptr T
  10. MyLen* = distinct int
  11. MySeq* = object
  12. ## Vectorized matrix
  13. len: MyLen # scalar size
  14. data: ptr UncheckedArray[float]
  15. proc `$`(x: MyLen): string {.borrow.}
  16. proc `==`(x1, x2: MyLen): bool {.borrow.}
  17. proc `=destroy`*(m: MySeq) {.inline.} =
  18. if m.data != nil:
  19. deallocShared(m.data)
  20. proc `=copy`*(m: var MySeq, m2: MySeq) =
  21. if m.data == m2.data: return
  22. if m.data != nil:
  23. `=destroy`(m)
  24. m.len = m2.len
  25. let bytes = m.len.int * sizeof(float)
  26. if bytes > 0:
  27. m.data = cast[ptr UncheckedArray[float]](allocShared(bytes))
  28. copyMem(m.data, m2.data, bytes)
  29. proc `=sink`*(m: var MySeq, m2: MySeq) {.inline.} =
  30. if m.data != m2.data:
  31. if m.data != nil:
  32. `=destroy`(m)
  33. m.len = m2.len
  34. m.data = m2.data
  35. proc len*(m: MySeq): MyLen {.inline.} = m.len
  36. proc lenx*(m: var MySeq): MyLen {.inline.} = m.len
  37. proc `[]`*(m: MySeq; i: MyLen): float {.inline.} =
  38. m.data[i.int]
  39. proc `[]`*(m: var MySeq; i: MyLen): var float {.inline.} =
  40. m.data[i.int]
  41. proc `[]=`*(m: var MySeq; i: MyLen, val: float) {.inline.} =
  42. m.data[i.int] = val
  43. proc setTo(s: var MySeq, val: float) =
  44. for i in 0..<s.len.int:
  45. s.data[i] = val
  46. proc newMySeq*(size: int, initial_value = 0.0): MySeq =
  47. result.len = size.MyLen
  48. if size > 0:
  49. result.data = cast[ptr UncheckedArray[float]](createShared(float, size))
  50. result.setTo(initial_value)
  51. converter literalToLen*(x: int{lit}): MyLen =
  52. x.MyLen
  53. #-------------------------------------------------------------
  54. # Unique pointer implementation
  55. #-------------------------------------------------------------
  56. proc `=destroy`*[T](p: UniquePtr[T]) =
  57. if p.val != nil:
  58. `=destroy`(p.val[])
  59. dealloc(p.val)
  60. proc `=copy`*[T](dest: var UniquePtr[T], src: UniquePtr[T]) {.error.}
  61. proc `=sink`*[T](dest: var UniquePtr[T], src: UniquePtr[T]) {.inline.} =
  62. if dest.val != nil and dest.val != src.val:
  63. `=destroy`(dest)
  64. dest.val = src.val
  65. proc newUniquePtr*[T](val: sink T): UniquePtr[T] =
  66. result.val = cast[type(result.val)](alloc(sizeof(result.val[])))
  67. reset(result.val[])
  68. result.val[] = val
  69. converter convertPtrToObj*[T](p: UniquePtr[T]): var T =
  70. result = p.val[]
  71. var pu = newUniquePtr(newMySeq(5, 1.0))
  72. let pu2 = newUniquePtr(newMySeq(5, 1.0))
  73. doAssert: pu.len == 5
  74. doAssert: pu2.len == 5
  75. doAssert: pu.lenx == 5
  76. doAssert: pu2.lenx == 5
  77. pu[0] = 2.0
  78. pu2[0] = 2.0
  79. doAssert pu[0] == 2.0
  80. doAssert: pu2[0] == 2.0
  81. ##-----------------------------------------------------------------------------------------
  82. ## Bugs #9735 and #9736
  83. type
  84. ConstPtr*[T] = object
  85. ## This pointer makes it impossible to change underlying value
  86. ## as it returns only `lent T`
  87. val: ptr T
  88. proc `=destroy`*[T](p: ConstPtr[T]) =
  89. if p.val != nil:
  90. `=destroy`(p.val[])
  91. dealloc(p.val)
  92. proc `=copy`*[T](dest: var ConstPtr[T], src: ConstPtr[T]) {.error.}
  93. proc `=sink`*[T](dest: var ConstPtr[T], src: ConstPtr[T]) {.inline.} =
  94. if dest.val != nil and dest.val != src.val:
  95. `=destroy`(dest)
  96. dest.val = src.val
  97. proc newConstPtr*[T](val: sink T): ConstPtr[T] =
  98. result.val = cast[type(result.val)](alloc(sizeof(result.val[])))
  99. reset(result.val[])
  100. result.val[] = val
  101. converter convertConstPtrToObj*[T](p: ConstPtr[T]): lent T =
  102. result = p.val[]
  103. var pc = newConstPtr(newMySeq(3, 1.0))
  104. let pc2 = newConstPtr(newMySeq(3, 1.0))
  105. doAssert: pc.len == 3
  106. doAssert: pc.len == 3
  107. doAssert: compiles(pc.lenx == 2) == false
  108. doAssert: compiles(pc2.lenx == 2) == false
  109. doAssert: compiles(pc[0] = 2.0) == false
  110. doAssert: compiles(pc2[0] = 2.0) == false
  111. doAssert: pc[0] == 1.0
  112. doAssert: pc2[0] == 1.0