summary refs log tree commit diff stats
path: root/tests
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2018-10-10 21:00:45 +0200
committerAndreas Rumpf <rumpf_a@web.de>2018-10-10 21:00:54 +0200
commit0803b532f44fc7b0039e31187af76e36828ca89d (patch)
treefe140126c06fb696ca90d9806408f72fa50cb475 /tests
parent6620b5dc8d231dfd846072aa060f414e5e2e3838 (diff)
downloadNim-0803b532f44fc7b0039e31187af76e36828ca89d.tar.gz
fixes #9263
Diffstat (limited to 'tests')
-rw-r--r--tests/destructor/tmatrix.nim117
1 files changed, 117 insertions, 0 deletions
diff --git a/tests/destructor/tmatrix.nim b/tests/destructor/tmatrix.nim
new file mode 100644
index 000000000..ba08ec4d6
--- /dev/null
+++ b/tests/destructor/tmatrix.nim
@@ -0,0 +1,117 @@
+discard """
+  output: '''after 3 3
+after 3 3
+after 2 2'''
+"""
+# bug #9263
+type
+  Matrix* = object
+    # Array for internal storage of elements.
+    data: ptr UncheckedArray[float]
+    # Row and column dimensions.
+    m*, n*: int
+
+var
+  allocCount, deallocCount: int
+
+proc `=destroy`*(m: var Matrix) =
+  if m.data != nil:
+    dealloc(m.data)
+    deallocCount.inc
+    m.data = nil
+    m.m = 0
+    m.n = 0
+
+proc `=sink`*(a: var Matrix; b: Matrix) =
+  if a.data != nil and a.data != b.data:
+    dealloc(a.data)
+    deallocCount.inc
+  a.data = b.data
+  a.m = b.m
+  a.n = b.n
+
+proc `=`*(a: var Matrix; b: Matrix) =
+  if a.data != nil and a.data != b.data:
+    dealloc(a.data)
+    deallocCount.inc
+    a.data = nil
+  a.m = b.m
+  a.n = b.n
+  if b.data != nil:
+    a.data = cast[type(a.data)](alloc(a.m * a.n * sizeof(float)))
+    allocCount.inc
+    copyMem(a.data, b.data, b.m * b.n * sizeof(float))
+
+proc matrix*(m, n: int, s: float): Matrix =
+  ## Construct an m-by-n constant matrix.
+  result.m = m
+  result.n = n
+  result.data = cast[type(result.data)](alloc(m * n * sizeof(float)))
+  allocCount.inc
+  for i in 0 ..< m * n:
+    result.data[i] = s
+
+proc `[]`*(m: Matrix, i, j: int): float {.inline.} =
+  ## Get a single element.
+  m.data[i * m.n + j]
+
+proc `[]`*(m: var Matrix, i, j: int): var float {.inline.} =
+  ## Get a single element.
+  m.data[i * m.n + j]
+
+proc `[]=`*(m: var Matrix, i, j: int, s: float) =
+  ## Set a single element.
+  m.data[i * m.n + j] = s
+
+proc `-`*(m: sink Matrix): Matrix =
+  ## Unary minus
+  result = m
+  for i in 0 ..< m.m:
+    for j in 0 ..< m.n:
+      result[i, j] = -m[i, j]
+
+proc `+`*(a: sink Matrix; b: Matrix): Matrix =
+  ## ``C = A + B``
+  assert(b.m == a.m and b.n == a.n, "Matrix dimensions must agree.")
+  result = a
+  for i in 0 ..< a.m:
+    for j in 0 ..< a.n:
+      result[i, j] = a[i, j] + b[i, j]
+
+proc `-`*(a: sink Matrix; b: Matrix): Matrix =
+  ## ``C = A - B``
+  assert(b.m == a.m and b.n == a.n, "Matrix dimensions must agree.")
+  result = a
+  for i in 0 ..< a.m:
+     for j in 0 ..< a.n:
+        result[i, j] = a[i, j] - b[i, j]
+
+proc info =
+  echo "after ", allocCount, " ", deallocCount
+  allocCount = 0
+  deallocCount = 0
+
+proc test1 =
+  var a = matrix(5, 5, 1.0)
+  var b = a
+  var c = a + b
+
+proc test2 =
+  var a = matrix(5, 5, 1.0)
+  var b = a
+  var c = -a
+
+proc test3 =
+  var a = matrix(5, 5, 1.0)
+  var b = matrix(5, 5, 2.0)
+  #    a = a - b
+  b = -b + a
+
+test1()
+info()
+
+test2()
+info()
+
+test3()
+info()