Skip to content

Commit 7b3586f

Browse files
committed
remove fake test
1 parent 683a138 commit 7b3586f

File tree

3 files changed

+218
-4
lines changed

3 files changed

+218
-4
lines changed

tests/tsmartptrs.nim

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import sync/smartptrs
2+
3+
block:
4+
var a1: UniquePtr[int]
5+
var a2 = newUniquePtr(0)
6+
7+
assert $a1 == "nil"
8+
assert a1.isNil
9+
assert $a2 == "(val: 0)"
10+
assert not a2.isNil
11+
assert a2[] == 0
12+
13+
# UniquePtr can't be copied but can be moved
14+
let a3 = move a2
15+
16+
assert $a2 == "nil"
17+
assert a2.isNil
18+
19+
assert $a3 == "(val: 0)"
20+
assert not a3.isNil
21+
assert a3[] == 0
22+
23+
a1 = newUniquePtr(int)
24+
a1[] = 1
25+
assert a1[] == 1
26+
var a4 = newUniquePtr(string)
27+
a4[] = "hello world"
28+
assert a4[] == "hello world"
29+
30+
block:
31+
var a1: SharedPtr[int]
32+
let a2 = newSharedPtr(0)
33+
let a3 = a2
34+
35+
assert $a1 == "nil"
36+
assert a1.isNil
37+
assert $a2 == "(val: 0)"
38+
assert not a2.isNil
39+
assert a2[] == 0
40+
assert $a3 == "(val: 0)"
41+
assert not a3.isNil
42+
assert a3[] == 0
43+
44+
a1 = newSharedPtr(int)
45+
a1[] = 1
46+
assert a1[] == 1
47+
var a4 = newSharedPtr(string)
48+
a4[] = "hello world"
49+
assert a4[] == "hello world"
50+
51+
block:
52+
var a1: ConstPtr[float]
53+
let a2 = newConstPtr(0)
54+
let a3 = a2
55+
56+
assert $a1 == "nil"
57+
assert a1.isNil
58+
assert $a2 == "(val: 0)"
59+
assert not a2.isNil
60+
assert a2[] == 0
61+
assert $a3 == "(val: 0)"
62+
assert not a3.isNil
63+
assert a3[] == 0

threading.nimble

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,3 @@ srcDir = "src"
1010
# Dependencies
1111

1212
requires "nim >= 1.4"
13-
14-
15-
task test, "runs the tests":
16-
exec "nim c -r tests/fake_test.nim"

threading/smartptrs.nim

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
#
2+
#
3+
# Nim's Runtime Library
4+
# (c) Copyright 2021 Nim contributors
5+
#
6+
# See the file "copying.txt", included in this
7+
# distribution, for details about the copyright.
8+
9+
## C++11 like smart pointers. They always use the shared allocator.
10+
import std/isolation, atomics2
11+
from typetraits import supportsCopyMem
12+
13+
template checkNotNil(p, msg: typed) =
14+
when compileOption("boundChecks"):
15+
{.line.}:
16+
if p.isNil:
17+
raise newException(NilAccessDefect, msg)
18+
19+
type
20+
UniquePtr*[T] = object
21+
## Non copyable pointer to a value of type `T` with exclusive ownership.
22+
val: ptr T
23+
24+
proc `=destroy`*[T](p: var UniquePtr[T]) =
25+
if p.val != nil:
26+
`=destroy`(p.val[])
27+
deallocShared(p.val)
28+
29+
proc `=copy`*[T](dest: var UniquePtr[T], src: UniquePtr[T]) {.error.}
30+
## The copy operation is disallowed for `UniquePtr`, it
31+
## can only be moved.
32+
33+
proc newUniquePtr*[T](val: sink Isolated[T]): UniquePtr[T] {.nodestroy.} =
34+
## Returns a unique pointer which has exclusive ownership of the value.
35+
result.val = cast[ptr T](allocShared(sizeof(T)))
36+
# thanks to '.nodestroy' we don't have to use allocShared0 here.
37+
# This is compiled into a copyMem operation, no need for a sink
38+
# here either.
39+
result.val[] = extract val
40+
# no destructor call for 'val: sink T' here either.
41+
42+
template newUniquePtr*[T](val: T): UniquePtr[T] =
43+
newUniquePtr(isolate(val))
44+
45+
proc newUniquePtr*[T](t: typedesc[T]): UniquePtr[T] =
46+
## Returns a unique pointer. It is not initialized,
47+
## so reading from it before writing to it is undefined behaviour!
48+
when not supportsCopyMem(T):
49+
result.val = cast[ptr T](allocShared0(sizeof(T)))
50+
else:
51+
result.val = cast[ptr T](allocShared(sizeof(T)))
52+
53+
proc isNil*[T](p: UniquePtr[T]): bool {.inline.} =
54+
p.val == nil
55+
56+
proc `[]`*[T](p: UniquePtr[T]): var T {.inline.} =
57+
## Returns a mutable view of the internal value of `p`.
58+
checkNotNil(p, "dereferencing nil unique pointer")
59+
p.val[]
60+
61+
proc `[]=`*[T](p: UniquePtr[T], val: sink Isolated[T]) {.inline.} =
62+
checkNotNil(p, "dereferencing nil unique pointer")
63+
p.val[] = extract val
64+
65+
template `[]=`*[T](p: UniquePtr[T]; val: T) =
66+
`[]=`(p, isolate(val))
67+
68+
proc `$`*[T](p: UniquePtr[T]): string {.inline.} =
69+
if p.val == nil: "nil"
70+
else: "(val: " & $p.val[] & ")"
71+
72+
#------------------------------------------------------------------------------
73+
74+
type
75+
SharedPtr*[T] = object
76+
## Shared ownership reference counting pointer.
77+
val: ptr tuple[value: T, counter: Atomic[int]]
78+
79+
proc `=destroy`*[T](p: var SharedPtr[T]) =
80+
if p.val != nil:
81+
if p.val[].counter.load(Consume) == 0:
82+
`=destroy`(p.val[])
83+
deallocShared(p.val)
84+
else:
85+
atomicDec(p.val[].counter)
86+
87+
proc `=copy`*[T](dest: var SharedPtr[T], src: SharedPtr[T]) =
88+
if src.val != nil:
89+
atomicInc(src.val[].counter)
90+
if dest.val != nil:
91+
`=destroy`(dest)
92+
dest.val = src.val
93+
94+
proc newSharedPtr*[T](val: sink Isolated[T]): SharedPtr[T] {.nodestroy.} =
95+
## Returns a shared pointer which shares
96+
## ownership of the object by reference counting.
97+
result.val = cast[typeof(result.val)](allocShared(sizeof(result.val[])))
98+
int(result.val.counter) = 0
99+
result.val.value = extract val
100+
101+
template newSharedPtr*[T](val: T): SharedPtr[T] =
102+
newSharedPtr(isolate(val))
103+
104+
proc newSharedPtr*[T](t: typedesc[T]): SharedPtr[T] =
105+
## Returns a shared pointer. It is not initialized,
106+
## so reading from it before writing to it is undefined behaviour!
107+
when not supportsCopyMem(T):
108+
result.val = cast[typeof(result.val)](allocShared0(sizeof(T)))
109+
else:
110+
result.val = cast[typeof(result.val)](allocShared(sizeof(T)))
111+
int(result.val.counter) = 0
112+
113+
proc isNil*[T](p: SharedPtr[T]): bool {.inline.} =
114+
p.val == nil
115+
116+
proc `[]`*[T](p: SharedPtr[T]): var T {.inline.} =
117+
checkNotNil(p, "dereferencing nil shared pointer")
118+
p.val.value
119+
120+
proc `[]=`*[T](p: SharedPtr[T], val: sink Isolated[T]) {.inline.} =
121+
checkNotNil(p, "dereferencing nil shared pointer")
122+
p.val.value = extract val
123+
124+
template `[]=`*[T](p: SharedPtr[T]; val: T) =
125+
`[]=`(p, isolate(val))
126+
127+
proc `$`*[T](p: SharedPtr[T]): string {.inline.} =
128+
if p.val == nil: "nil"
129+
else: "(val: " & $p.val.value & ")"
130+
131+
#------------------------------------------------------------------------------
132+
133+
type
134+
ConstPtr*[T] = distinct SharedPtr[T]
135+
## Distinct version of `SharedPtr[T]`, which doesn't allow mutating the underlying value.
136+
137+
proc newConstPtr*[T](val: sink Isolated[T]): ConstPtr[T] {.nodestroy, inline.} =
138+
## Similar to `newSharedPtr<#newSharedPtr,T>`_, but the underlying value can't be mutated.
139+
ConstPtr[T](newSharedPtr(val))
140+
141+
template newConstPtr*[T](val: T): ConstPtr[T] =
142+
newConstPtr(isolate(val))
143+
144+
proc isNil*[T](p: ConstPtr[T]): bool {.inline.} =
145+
SharedPtr[T](p).val == nil
146+
147+
proc `[]`*[T](p: ConstPtr[T]): lent T {.inline.} =
148+
## Returns an immutable view of the internal value of `p`.
149+
checkNotNil(p, "dereferencing nil const pointer")
150+
SharedPtr[T](p).val.value
151+
152+
proc `[]=`*[T](p: ConstPtr[T], v: T) = {.error: "`ConstPtr` cannot be assigned.".}
153+
154+
proc `$`*[T](p: ConstPtr[T]): string {.inline.} =
155+
$SharedPtr[T](p)

0 commit comments

Comments
 (0)