topttree.nim 2.0 KB

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