ttuple.nim 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. discard """
  2. output: '''5.0 10.0
  3. =destroy
  4. =destroy
  5. '''
  6. """
  7. type
  8. MyOpt[T] = object
  9. case has: bool:
  10. of true: val: T
  11. of false: nil
  12. MyVal = object
  13. f: ptr float
  14. proc `=destroy`(x: var MyVal) =
  15. if x.f != nil:
  16. dealloc(x.f)
  17. proc `=sink`(x1: var MyVal, x2: Myval) =
  18. if x1.f != x2.f:
  19. `=destroy`(x1)
  20. x1.f = x2.f
  21. proc `=`(x1: var MyVal, x2: Myval) =
  22. if x1.f != x2.f:
  23. `=destroy`(x1)
  24. x1.f = create(float)
  25. x1.f[] = x2.f[]
  26. proc newVal(x: float): MyVal =
  27. result.f = create(float)
  28. result.f[] = x
  29. template getIt[T, R](self: MyOpt[T], body: untyped, default: R): R =
  30. if self.has:
  31. template it: untyped {.inject.} = self.val
  32. body
  33. else:
  34. default
  35. proc myproc(h: MyOpt[float]) =
  36. let (a, b) = h.getIt((newVal(it), newVal(it * 2)), (newVal(1.0), newVal(1.0)))
  37. echo a.f[], " ", b.f[]
  38. let h = MyOpt[float](has: true, val: 5.0)
  39. myproc(h)
  40. #-------------------------------------------------------------
  41. type
  42. MyObject* = object
  43. len*: int
  44. amount: UncheckedArray[float]
  45. MyObjPtr* = ptr MyObject
  46. MyObjContainer* {.byref.} = object
  47. size1: int
  48. size2: int
  49. data: ptr UncheckedArray[MyObjPtr]
  50. proc size1*(m: MyObjContainer): int {.inline.} = m.size1
  51. proc size2*(m: MyObjContainer): int {.inline.} = m.size2
  52. proc allocateMyObjPtr(size2: int): MyObjPtr =
  53. cast[MyObjPtr](allocShared(sizeof(MyObject) + sizeof(float) * size2.int))
  54. proc `=destroy`*(m: var MyObjContainer) {.inline.} =
  55. if m.data != nil:
  56. for i in 0..<m.size1:
  57. if m.data[i] != nil:
  58. deallocShared(m.data[i])
  59. m.data[i] = nil
  60. deallocShared(m.data)
  61. echo "=destroy"
  62. m.data = nil
  63. proc `=sink`*(m: var MyObjContainer, m2: MyObjContainer) {.inline.} =
  64. if m.data != m2.data:
  65. `=destroy`(m)
  66. m.size1 = m2.size1
  67. m.size2 = m2.size2
  68. m.data = m2.data
  69. proc `=`*(m: var MyObjContainer, m2: MyObjContainer) {.error.}
  70. ## non copyable
  71. func newMyObjContainer*(size2: Natural): MyObjContainer =
  72. result.size2 = size2
  73. proc push(m: var MyObjContainer, cf: MyObjPtr) =
  74. ## Add MyObjPtr to MyObjContainer, shallow copy
  75. m.size1.inc
  76. m.data = cast[ptr UncheckedArray[MyObjPtr]](reallocShared(m.data, m.size1 * sizeof(MyObjPtr)))
  77. m.data[m.size1 - 1] = cf
  78. proc add*(m: var MyObjContainer, amount: float) =
  79. assert m.size2 > 0, "MyObjContainer is not initialized, use newMyObjContainer() to initialize object before use"
  80. let cf = allocateMyObjPtr(m.size2)
  81. for i in 0..<m.size2:
  82. cf.amount[i.int] = amount
  83. m.push(cf)
  84. proc add*(dest: var MyObjContainer, src: sink MyObjContainer) =
  85. # merge containers
  86. for i in 0..<src.size1:
  87. dest.push src.data[i]
  88. src.data[i] = nil
  89. proc test =
  90. var cf1 = newMyObjContainer(100)
  91. cf1.add(1)
  92. cf1.add(2)
  93. var cf3 = newMyObjContainer(100)
  94. cf3.add(2)
  95. cf3.add(3)
  96. cf1.add(cf3)
  97. test()