summary refs log tree commit diff stats
path: root/tests/destructor/tmatrix.nim
blob: a16bfa37b8a27b32f70f72c8e25412b673ed07c1 (plain) (blame)
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
discard """
  output: '''after 2 2
after 2 2
after 2 2
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

proc test4 =
  # bug #9294
  var a = matrix(5, 5, 1.0)
  a = -a + a

test1()
info()

test2()
info()

test3()
info()

test4()
info()