File: tcyclic.nim

package info (click to toggle)
nim 2.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,911,644 kB
  • sloc: sh: 24,603; ansic: 1,761; python: 1,492; makefile: 1,013; sql: 298; asm: 141; xml: 13
file content (135 lines) | stat: -rw-r--r-- 2,199 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
## todo publish the `isCyclic` when it's mature.
proc isCyclic(t: typedesc): bool {.magic: "TypeTrait".} =
  ## Returns true if the type can potentially form a cyclic type

template cyclicYes(x: typed) =
  doAssert isCyclic(x)

template cyclicNo(x: typed) =
  doAssert not isCyclic(x)

# atomic types are not cyclic
cyclicNo(int)
cyclicNo(float)
cyclicNo(string)
cyclicNo(char)
cyclicNo(void)

type
  Object = object
  Ref = ref object

cyclicNo(Object)
cyclicNo(Ref)

type
  Data1 = ref object
  Data2 = ref object
    id: Data1

cyclicNo(Data2)

type
  Cyclone = ref object
    data: Cyclone

  Alias = Cyclone

  Acyclic {.acyclic.} = ref object
    data: Acyclic

  LinkedNode = object
    next: ref LinkedNode

  LinkedNodeWithCursor = object
    next {.cursor.} : ref LinkedNodeWithCursor

cyclicYes(Cyclone)
cyclicYes(Alias)
cyclicNo(seq[Cyclone])
cyclicNo((Cyclone, ))
cyclicNo(Acyclic)

cyclicYes(LinkedNode)
cyclicNo(LinkedNodeWithCursor) # cursor doesn't increase rc, cannot form a cycle

type
  ObjectWithoutCycles = object
    data: seq[ObjectWithoutCycles]

cyclicNo(ObjectWithoutCycles)


block:
  type
    Try = object
      id: Best
    Best = object
      name: ref Try
    Best2 = ref Best

  cyclicYes(Best)
  cyclicYes(Try)
  cyclicNo(Best2)

  type
    Base = object
      data: ref seq[Base]
    Base2 = ref Base

  cyclicYes(Base)
  cyclicNo(Base2)


  type
    Base3 = ref object
      id: Base3

    Base4 = object
      id: ref Base4

  cyclicYes(Base3)
  cyclicYes(Base4)
  cyclicYes(ref Base4)

block:
  type Cyclic2 = object
    x: ref (Cyclic2, int)

  cyclicYes (Cyclic2, int)
  cyclicYes (ref (Cyclic2, int))

block:
  type
    myseq[T] = object
      data: ptr UncheckedArray[T]
    Node = ref object
      kids: myseq[Node]

  cyclicNo(Node)

block:
  type
    myseq[T] = object
      data: ptr UncheckedArray[T]
    Node = ref object
      kids: myseq[Node]

  proc `=trace`(x: var myseq[Node]; env: pointer) = discard

  cyclicYes(Node)

block:
  type
    Foo = object
      id: ptr ref Foo

  cyclicNo(Foo)

block:
  type
    InheritableObj = object of RootObj
    InheritableRef = ref object of RootObj

  cyclicYes(InheritableObj)
  cyclicYes(InheritableRef)