tcyclic.nim 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. ## todo publish the `isCyclic` when it's mature.
  2. proc isCyclic(t: typedesc): bool {.magic: "TypeTrait".} =
  3. ## Returns true if the type can potentially form a cyclic type
  4. template cyclicYes(x: typed) =
  5. doAssert isCyclic(x)
  6. template cyclicNo(x: typed) =
  7. doAssert not isCyclic(x)
  8. # atomic types are not cyclic
  9. cyclicNo(int)
  10. cyclicNo(float)
  11. cyclicNo(string)
  12. cyclicNo(char)
  13. cyclicNo(void)
  14. type
  15. Object = object
  16. Ref = ref object
  17. cyclicNo(Object)
  18. cyclicNo(Ref)
  19. type
  20. Data1 = ref object
  21. Data2 = ref object
  22. id: Data1
  23. cyclicNo(Data2)
  24. type
  25. Cyclone = ref object
  26. data: Cyclone
  27. Alias = Cyclone
  28. Acyclic {.acyclic.} = ref object
  29. data: Acyclic
  30. LinkedNode = object
  31. next: ref LinkedNode
  32. LinkedNodeWithCursor = object
  33. next {.cursor.} : ref LinkedNodeWithCursor
  34. cyclicYes(Cyclone)
  35. cyclicYes(Alias)
  36. cyclicNo(seq[Cyclone])
  37. cyclicNo((Cyclone, ))
  38. cyclicNo(Acyclic)
  39. cyclicYes(LinkedNode)
  40. cyclicNo(LinkedNodeWithCursor) # cursor doesn't increase rc, cannot form a cycle
  41. type
  42. ObjectWithoutCycles = object
  43. data: seq[ObjectWithoutCycles]
  44. cyclicNo(ObjectWithoutCycles)
  45. block:
  46. type
  47. Try = object
  48. id: Best
  49. Best = object
  50. name: ref Try
  51. Best2 = ref Best
  52. cyclicYes(Best)
  53. cyclicYes(Try)
  54. cyclicNo(Best2)
  55. type
  56. Base = object
  57. data: ref seq[Base]
  58. Base2 = ref Base
  59. cyclicYes(Base)
  60. cyclicNo(Base2)
  61. type
  62. Base3 = ref object
  63. id: Base3
  64. Base4 = object
  65. id: ref Base4
  66. cyclicYes(Base3)
  67. cyclicYes(Base4)
  68. cyclicYes(ref Base4)
  69. block:
  70. type Cyclic2 = object
  71. x: ref (Cyclic2, int)
  72. cyclicYes (Cyclic2, int)
  73. cyclicYes (ref (Cyclic2, int))
  74. block:
  75. type
  76. myseq[T] = object
  77. data: ptr UncheckedArray[T]
  78. Node = ref object
  79. kids: myseq[Node]
  80. cyclicNo(Node)
  81. block:
  82. type
  83. myseq[T] = object
  84. data: ptr UncheckedArray[T]
  85. Node = ref object
  86. kids: myseq[Node]
  87. proc `=trace`(x: var myseq[Node]; env: pointer) = discard
  88. cyclicYes(Node)
  89. block:
  90. type
  91. Foo = object
  92. id: ptr ref Foo
  93. cyclicNo(Foo)
  94. block:
  95. type
  96. InheritableObj = object of RootObj
  97. InheritableRef = ref object of RootObj
  98. cyclicYes(InheritableObj)
  99. cyclicYes(InheritableRef)