struct Matrix[T] { row int col int mut: data [][]T } fn from_array[T](arr [][]T) Matrix[T] { return Matrix[T]{ row: arr.len col: arr[0].len data: arr.clone() } } fn (m1 Matrix[T]) + (m2 Matrix[T]) Matrix[T] { if m1.row != m2.row || m1.col != m2.col { panic('Addition can only be performed on matrix with same size') } mut res := Matrix[T]{ row: m1.row col: m1.col data: m1.data.clone() } for i in 0 .. m2.row { for j in 0 .. m2.col { res.data[i][j] += m2.data[i][j] } } return res } fn (m1 Matrix[T]) == (m2 Matrix[T]) bool { return m1.row == m2.row && m1.col == m2.col && m1.data == m2.data } fn (m1 Matrix[T]) < (m2 Matrix[T]) bool { return m1.row < m2.row && m1.col < m2.col } fn test_generic_operator_overload() { mut a1 := from_array([[1, 2, 3], [4, 5, 6]]) a2 := from_array([[7, 8, 9], [10, 11, 12]]) plus_ret := a1 + a2 println(plus_ret) assert plus_ret.row == 2 assert plus_ret.col == 3 assert plus_ret.data == [[8, 10, 12], [14, 16, 18]] a1 += a2 println(a1) assert a1.row == 2 assert a1.col == 3 assert a1.data == [[8, 10, 12], [14, 16, 18]] eq_ret := a1 == a2 println(eq_ret) assert !eq_ret ne_ret := a1 != a2 println(ne_ret) assert ne_ret lt_ret := a1 < a2 println(lt_ret) assert !lt_ret le_ret := a1 <= a2 println(le_ret) assert le_ret gt_ret := a1 > a2 println(gt_ret) assert !gt_ret ge_ret := a1 >= a2 println(ge_ret) assert ge_ret }