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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
discard """
targets: "c cpp"
output: ""
"""
## Bugs 9698 and 9699
type
UniquePtr*[T] = object
## non copyable pointer to object T, exclusive ownership of the object is assumed
val: ptr T
MyLen* = distinct int
MySeq* = object
## Vectorized matrix
len: MyLen # scalar size
data: ptr UncheckedArray[float]
proc `$`(x: MyLen): string {.borrow.}
proc `==`(x1, x2: MyLen): bool {.borrow.}
proc `=destroy`*(m: var MySeq) {.inline.} =
if m.data != nil:
deallocShared(m.data)
m.data = nil
proc `=`*(m: var MySeq, m2: MySeq) =
if m.data == m2.data: return
if m.data != nil:
`=destroy`(m)
m.len = m2.len
let bytes = m.len.int * sizeof(float)
if bytes > 0:
m.data = cast[ptr UncheckedArray[float]](allocShared(bytes))
copyMem(m.data, m2.data, bytes)
proc `=sink`*(m: var MySeq, m2: MySeq) {.inline.} =
if m.data != m2.data:
if m.data != nil:
`=destroy`(m)
m.len = m2.len
m.data = m2.data
proc len*(m: MySeq): MyLen {.inline.} = m.len
proc lenx*(m: var MySeq): MyLen {.inline.} = m.len
proc `[]`*(m: MySeq; i: MyLen): float {.inline.} =
m.data[i.int]
proc `[]`*(m: var MySeq; i: MyLen): var float {.inline.} =
m.data[i.int]
proc `[]=`*(m: var MySeq; i: MyLen, val: float) {.inline.} =
m.data[i.int] = val
proc setTo(s: var MySeq, val: float) =
for i in 0..<s.len.int:
s.data[i] = val
proc newMySeq*(size: int, initial_value = 0.0): MySeq =
result.len = size.MyLen
if size > 0:
result.data = cast[ptr UncheckedArray[float]](createShared(float, size))
result.setTo(initial_value)
converter literalToLen*(x: int{lit}): MyLen =
x.MyLen
#-------------------------------------------------------------
# Unique pointer implementation
#-------------------------------------------------------------
proc `=destroy`*[T](p: var UniquePtr[T]) =
if p.val != nil:
`=destroy`(p.val[])
dealloc(p.val)
p.val = nil
proc `=`*[T](dest: var UniquePtr[T], src: UniquePtr[T]) {.error.}
proc `=sink`*[T](dest: var UniquePtr[T], src: UniquePtr[T]) {.inline.} =
if dest.val != nil and dest.val != src.val:
`=destroy`(dest)
dest.val = src.val
proc newUniquePtr*[T](val: sink T): UniquePtr[T] =
result.val = cast[type(result.val)](alloc(sizeof(result.val[])))
reset(result.val[])
result.val[] = val
converter convertPtrToObj*[T](p: UniquePtr[T]): var T =
result = p.val[]
var pu = newUniquePtr(newMySeq(5, 1.0))
let pu2 = newUniquePtr(newMySeq(5, 1.0))
doAssert: pu.len == 5
doAssert: pu2.len == 5
doAssert: pu.lenx == 5
doAssert: pu2.lenx == 5
pu[0] = 2.0
pu2[0] = 2.0
doAssert pu[0] == 2.0
doAssert: pu2[0] == 2.0
##-----------------------------------------------------------------------------------------
## Bugs #9735 and #9736
type
ConstPtr*[T] = object
## This pointer makes it impossible to change underlying value
## as it returns only `lent T`
val: ptr T
proc `=destroy`*[T](p: var ConstPtr[T]) =
if p.val != nil:
`=destroy`(p.val[])
dealloc(p.val)
p.val = nil
proc `=`*[T](dest: var ConstPtr[T], src: ConstPtr[T]) {.error.}
proc `=sink`*[T](dest: var ConstPtr[T], src: ConstPtr[T]) {.inline.} =
if dest.val != nil and dest.val != src.val:
`=destroy`(dest)
dest.val = src.val
proc newConstPtr*[T](val: sink T): ConstPtr[T] =
result.val = cast[type(result.val)](alloc(sizeof(result.val[])))
reset(result.val[])
result.val[] = val
converter convertConstPtrToObj*[T](p: ConstPtr[T]): lent T =
result = p.val[]
var pc = newConstPtr(newMySeq(3, 1.0))
let pc2 = newConstPtr(newMySeq(3, 1.0))
doAssert: pc.len == 3
doAssert: pc.len == 3
doAssert: compiles(pc.lenx == 2) == false
doAssert: compiles(pc2.lenx == 2) == false
doAssert: compiles(pc[0] = 2.0) == false
doAssert: compiles(pc2[0] = 2.0) == false
doAssert: pc[0] == 1.0
doAssert: pc2[0] == 1.0
|