tconverter_unique_ptr.nim 3.7 KB

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