tdeepcopy.nim 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. discard """
  2. matrix: "--mm:refc; --mm:orc --deepcopy:on"
  3. output: "ok"
  4. """
  5. import tables, lists
  6. type
  7. ListTable[K, V] = object
  8. valList: DoublyLinkedList[V]
  9. table: Table[K, DoublyLinkedNode[V]]
  10. ListTableRef*[K, V] = ref ListTable[K, V]
  11. proc initListTable*[K, V](initialSize = 64): ListTable[K, V] =
  12. result.valList = initDoublyLinkedList[V]()
  13. result.table = initTable[K, DoublyLinkedNode[V]]()
  14. proc newListTable*[K, V](initialSize = 64): ListTableRef[K, V] =
  15. new(result)
  16. result[] = initListTable[K, V](initialSize)
  17. proc `[]=`*[K, V](t: var ListTable[K, V], key: K, val: V) =
  18. if key in t.table:
  19. t.table[key].value = val
  20. else:
  21. let node = newDoublyLinkedNode(val)
  22. t.valList.append(node)
  23. t.table[key] = node
  24. proc `[]`*[K, V](t: ListTable[K, V], key: K): var V {.inline.} =
  25. result = t.table[key].value
  26. proc len*[K, V](t: ListTable[K, V]): Natural {.inline.} =
  27. result = t.table.len
  28. iterator values*[K, V](t: ListTable[K, V]): V =
  29. for val in t.valList.items():
  30. yield val
  31. proc `[]=`*[K, V](t: ListTableRef[K, V], key: K, val: V) =
  32. t[][key] = val
  33. proc `[]`*[K, V](t: ListTableRef[K, V], key: K): var V {.inline.} =
  34. t[][key]
  35. proc len*[K, V](t: ListTableRef[K, V]): Natural {.inline.} =
  36. t[].len
  37. iterator values*[K, V](t: ListTableRef[K, V]): V =
  38. for val in t[].values:
  39. yield val
  40. proc main() =
  41. type SomeObj = ref object
  42. for outer in 0..10_000:
  43. let myObj = new(SomeObj)
  44. let table = newListTable[int, SomeObj]()
  45. table[0] = myObj
  46. for i in 1..100:
  47. table[i] = new(SomeObj)
  48. var myObj2: SomeObj
  49. for val in table.values():
  50. if myObj2.isNil:
  51. myObj2 = val
  52. doAssert(myObj == myObj2) # passes
  53. var tableCopy: ListTableRef[int, SomeObj]
  54. deepCopy(tableCopy, table)
  55. let myObjCopy = tableCopy[0]
  56. var myObjCopy2: SomeObj = nil
  57. for val in tableCopy.values():
  58. if myObjCopy2.isNil:
  59. myObjCopy2 = val
  60. #echo cast[int](myObj)
  61. #echo cast[int](myObjCopy)
  62. #echo cast[int](myObjCopy2)
  63. doAssert(myObjCopy == myObjCopy2) # fails
  64. type
  65. PtrTable = object
  66. counter, max: int
  67. data: array[0..99, (pointer, pointer)]
  68. doAssert(sizeof(PtrTable) == 2*sizeof(int)+sizeof(pointer)*2*100)
  69. main()
  70. echo "ok"