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
|
discard """
output: '''----
myobj constructed
myobj destroyed
----
mygeneric1 constructed
mygeneric1 destroyed
----
mygeneric2 constructed
mygeneric2 destroyed
myobj destroyed
----
mygeneric3 constructed
mygeneric1 destroyed
----
mygeneric1 destroyed
----
myobj destroyed
----
----
myobj destroyed
'''
"""
type
TMyObj = object
x, y: int
p: pointer
TMyGeneric1[T] = object
x: T
TMyGeneric2[A, B] = object
x: A
y: B
TMyGeneric3[A, B, C] = object
x: A
y: B
z: C
TObjKind = enum A, B, C, D
TCaseObj = object
case kind: TObjKind
of A:
x: TMyGeneric1[int]
of B, C:
y: TMyObj
else:
case innerKind: TObjKind
of A, B, C:
p: TMyGeneric3[int, float, string]
of D:
q: TMyGeneric3[TMyObj, int, int]
r: string
proc destroy(o: var TMyObj) {.override.} =
if o.p != nil: dealloc o.p
echo "myobj destroyed"
proc destroy(o: var TMyGeneric1) {.override.} =
echo "mygeneric1 destroyed"
proc destroy[A, B](o: var TMyGeneric2[A, B]) {.override.} =
echo "mygeneric2 destroyed"
proc open: TMyObj =
# allow for superfluous ()
result = (TMyObj(x: 1, y: 2, p: alloc(3)))
proc `$`(x: TMyObj): string = $x.y
proc myobj() =
var x = open()
echo "myobj constructed"
proc mygeneric1() =
var x = TMyGeneric1[int](x: 10)
echo "mygeneric1 constructed"
proc mygeneric2[T](val: T) =
var a = open()
var b = TMyGeneric2[int, T](x: 10, y: val)
echo "mygeneric2 constructed"
var c = TMyGeneric3[int, int, string](x: 10, y: 20, z: "test")
proc mygeneric3 =
var x = TMyGeneric3[int, string, TMyGeneric1[int]](
x: 10, y: "test", z: TMyGeneric1[int](x: 10))
echo "mygeneric3 constructed"
echo "----"
myobj()
echo "----"
mygeneric1()
echo "----"
mygeneric2[int](10)
echo "----"
mygeneric3()
proc caseobj =
block:
echo "----"
var o1 = TCaseObj(kind: A, x: TMyGeneric1[int](x: 10))
block:
echo "----"
var o2 = TCaseObj(kind: B, y: open())
block:
echo "----"
var o3 = TCaseObj(kind: D, innerKind: B, r: "test",
p: TMyGeneric3[int, float, string](x: 10, y: 1.0, z: "test"))
block:
echo "----"
var o4 = TCaseObj(kind: D, innerKind: D, r: "test",
q: TMyGeneric3[TMyObj, int, int](x: open(), y: 1, z: 0))
caseobj()
|