topttree.nim 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. discard """
  2. disabled: i386
  3. output: '''10.0
  4. 60.0
  5. 90.0
  6. 120.0
  7. 10.0
  8. 60.0
  9. 90.0
  10. 120.0
  11. 8 8'''
  12. joinable: false
  13. """
  14. import typetraits
  15. type
  16. opt[T] = object
  17. data: ptr T
  18. var
  19. allocCount, deallocCount: int
  20. proc `=destroy`*[T](x: var opt[T]) =
  21. if x.data != nil:
  22. mixin `=destroy`
  23. when not supportsCopyMem(T):
  24. `=destroy`(x.data[])
  25. dealloc(x.data)
  26. inc deallocCount
  27. x.data = nil
  28. proc `=`*[T](a: var opt[T]; b: opt[T]) =
  29. if a.data == b.data: return
  30. if a.data != nil:
  31. dealloc(a.data)
  32. inc deallocCount
  33. a.data = nil
  34. if b.data != nil:
  35. a.data = cast[type(a.data)](alloc(sizeof(T)))
  36. inc allocCount
  37. when supportsCopyMem(T):
  38. copyMem(a.data, b.data, sizeof(T))
  39. else:
  40. a.data[] = b.data[]
  41. proc `=sink`*[T](a: var opt[T]; b: opt[T]) =
  42. if a.data != nil and a.data != b.data:
  43. dealloc(a.data)
  44. inc deallocCount
  45. a.data = b.data
  46. proc createOpt*[T](x: T): opt[T] =
  47. result.data = cast[type(result.data)](alloc(sizeof(T)))
  48. inc allocCount
  49. result.data[] = x
  50. template `[]`[T](x: opt[T]): T =
  51. assert x.p != nil, "attempt to read from moved/destroyed value"
  52. x.p[]
  53. template `?=`[T](it: untyped; x: opt[T]): bool =
  54. template it: untyped {.inject.} = x.data[]
  55. if x.data != nil:
  56. true
  57. else:
  58. false
  59. type
  60. Tree = object
  61. data: float
  62. le, ri: opt[Tree]
  63. proc createTree(data: float): Tree =
  64. result.data = data
  65. proc insert(t: var opt[Tree]; newVal: float) =
  66. #if it ?= t:
  67. if t.data != nil:
  68. if newVal < t.data[].data:
  69. insert(t.data[].le, newVal)
  70. elif t.data[].data < newVal:
  71. insert(t.data[].ri, newVal)
  72. else:
  73. discard "already in the tree"
  74. else:
  75. t = createOpt(Tree(data: newVal))
  76. proc write(t: opt[Tree]) =
  77. if it ?= t:
  78. write(it.le)
  79. write stdout, it.data, "\n"
  80. write(it.ri)
  81. proc use(t: opt[Tree]) = discard
  82. proc main =
  83. var t: opt[Tree]
  84. insert t, 60.0
  85. insert t, 90.0
  86. insert t, 10.0
  87. insert t, 120.0
  88. write t
  89. let copy = t
  90. write copy
  91. use t
  92. main()
  93. echo allocCount, " ", deallocCount