tcustomseqs.nim 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. discard """
  2. output: '''1
  3. 2
  4. 3
  5. 4
  6. 5
  7. 6
  8. 89
  9. 90
  10. 90
  11. 0 0 1
  12. 0 1 2
  13. 0 2 3
  14. 1 0 4
  15. 1 1 5
  16. 1 2 6
  17. 1 3 7
  18. after 6 6'''
  19. joinable: false
  20. """
  21. import typetraits
  22. type
  23. myseq*[T] = object
  24. len, cap: int
  25. data: ptr UncheckedArray[T]
  26. # XXX make code memory safe for overflows in '*'
  27. var
  28. allocCount, deallocCount: int
  29. proc `=destroy`*[T](x: var myseq[T]) =
  30. if x.data != nil:
  31. when not supportsCopyMem(T):
  32. for i in 0..<x.len: `=destroy`(x[i])
  33. dealloc(x.data)
  34. inc deallocCount
  35. x.data = nil
  36. x.len = 0
  37. x.cap = 0
  38. proc `=`*[T](a: var myseq[T]; b: myseq[T]) =
  39. if a.data == b.data: return
  40. if a.data != nil:
  41. `=destroy`(a)
  42. #dealloc(a.data)
  43. #inc deallocCount
  44. #a.data = nil
  45. a.len = b.len
  46. a.cap = b.cap
  47. if b.data != nil:
  48. a.data = cast[type(a.data)](alloc(a.cap * sizeof(T)))
  49. inc allocCount
  50. when supportsCopyMem(T):
  51. copyMem(a.data, b.data, a.cap * sizeof(T))
  52. else:
  53. for i in 0..<a.len:
  54. a.data[i] = b.data[i]
  55. proc `=sink`*[T](a: var myseq[T]; b: myseq[T]) =
  56. if a.data != nil and a.data != b.data:
  57. dealloc(a.data)
  58. inc deallocCount
  59. a.len = b.len
  60. a.cap = b.cap
  61. a.data = b.data
  62. proc resize[T](s: var myseq[T]) =
  63. if s.cap == 0: s.cap = 8
  64. else: s.cap = (s.cap * 3) shr 1
  65. if s.data == nil: inc allocCount
  66. s.data = cast[type(s.data)](realloc(s.data, s.cap * sizeof(T)))
  67. proc reserveSlot[T](x: var myseq[T]): ptr T =
  68. if x.len >= x.cap: resize(x)
  69. result = addr(x.data[x.len])
  70. inc x.len
  71. template add*[T](x: var myseq[T]; y: T) =
  72. reserveSlot(x)[] = y
  73. proc shrink*[T](x: var myseq[T]; newLen: int) =
  74. assert newLen <= x.len
  75. assert newLen >= 0
  76. when not supportsCopyMem(T):
  77. for i in countdown(x.len - 1, newLen - 1):
  78. `=destroy`(x.data[i])
  79. x.len = newLen
  80. proc grow*[T](x: var myseq[T]; newLen: int; value: T) =
  81. if newLen <= x.len: return
  82. assert newLen >= 0
  83. if x.cap == 0: x.cap = newLen
  84. else: x.cap = max(newLen, (x.cap * 3) shr 1)
  85. if x.data == nil: inc allocCount
  86. x.data = cast[type(x.data)](realloc(x.data, x.cap * sizeof(T)))
  87. for i in x.len..<newLen:
  88. x.data[i] = value
  89. x.len = newLen
  90. template default[T](t: typedesc[T]): T =
  91. var v: T
  92. v
  93. proc setLen*[T](x: var myseq[T]; newLen: int) {.deprecated.} =
  94. if newlen < x.len: shrink(x, newLen)
  95. else: grow(x, newLen, default(T))
  96. template `[]`*[T](x: myseq[T]; i: Natural): T =
  97. assert i < x.len
  98. x.data[i]
  99. template `[]=`*[T](x: myseq[T]; i: Natural; y: T) =
  100. assert i < x.len
  101. x.data[i] = y
  102. proc createSeq*[T](elems: varargs[T]): myseq[T] =
  103. result.cap = elems.len
  104. result.len = elems.len
  105. result.data = cast[type(result.data)](alloc(result.cap * sizeof(T)))
  106. inc allocCount
  107. when supportsCopyMem(T):
  108. copyMem(result.data, unsafeAddr(elems[0]), result.cap * sizeof(T))
  109. else:
  110. for i in 0..<result.len:
  111. result.data[i] = elems[i]
  112. proc len*[T](x: myseq[T]): int {.inline.} = x.len
  113. proc main =
  114. var s = createSeq(1, 2, 3, 4, 5, 6)
  115. s.add 89
  116. s.grow s.len + 2, 90
  117. for i in 0 ..< s.len:
  118. echo s[i]
  119. var nested = createSeq(createSeq(1, 2, 3), createSeq(4, 5, 6, 7))
  120. for i in 0 ..< nested.len:
  121. for j in 0 ..< nested[i].len:
  122. echo i, " ", j, " ", nested[i][j]
  123. main()
  124. echo "after ", allocCount, " ", deallocCount