topttree.nim 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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. cmd: '''nim c --newruntime $file'''
  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. when not supportsCopyMem(T):
  22. `=destroy`(x.data[])
  23. dealloc(x.data)
  24. inc deallocCount
  25. x.data = nil
  26. proc `=`*[T](a: var opt[T]; b: opt[T]) =
  27. if a.data == b.data: return
  28. if a.data != nil:
  29. dealloc(a.data)
  30. inc deallocCount
  31. a.data = nil
  32. if b.data != nil:
  33. a.data = cast[type(a.data)](alloc(sizeof(T)))
  34. inc allocCount
  35. when supportsCopyMem(T):
  36. copyMem(a.data, b.data, sizeof(T))
  37. else:
  38. a.data[] = b.data[]
  39. proc `=sink`*[T](a: var opt[T]; b: opt[T]) =
  40. if a.data != nil and a.data != b.data:
  41. dealloc(a.data)
  42. inc deallocCount
  43. a.data = b.data
  44. proc createOpt*[T](x: T): opt[T] =
  45. result.data = cast[type(result.data)](alloc(sizeof(T)))
  46. inc allocCount
  47. result.data[] = x
  48. template `[]`[T](x: opt[T]): T =
  49. assert x.p != nil, "attempt to read from moved/destroyed value"
  50. x.p[]
  51. template `?=`[T](it: untyped; x: opt[T]): bool =
  52. template it: untyped {.inject.} = x.data[]
  53. if x.data != nil:
  54. true
  55. else:
  56. false
  57. type
  58. Tree = object
  59. data: float
  60. le, ri: opt[Tree]
  61. proc createTree(data: float): Tree =
  62. result.data = data
  63. proc insert(t: var opt[Tree]; newVal: float) =
  64. #if it ?= t:
  65. if t.data != nil:
  66. if newVal < t.data[].data:
  67. insert(t.data[].le, newVal)
  68. elif t.data[].data < newVal:
  69. insert(t.data[].ri, newVal)
  70. else:
  71. discard "already in the tree"
  72. else:
  73. t = createOpt(Tree(data: newVal))
  74. proc write(t: opt[Tree]) =
  75. if it ?= t:
  76. write(it.le)
  77. write stdout, it.data, "\n"
  78. write(it.ri)
  79. proc main =
  80. var t: opt[Tree]
  81. insert t, 60.0
  82. insert t, 90.0
  83. insert t, 10.0
  84. insert t, 120.0
  85. write t
  86. let copy = t
  87. write copy
  88. main()
  89. echo allocCount, " ", deallocCount