RapidFuzz
Loading...
Searching...
No Matches
Matrix.hpp
1/* SPDX-License-Identifier: MIT */
2/* Copyright (c) 2022 Max Bachmann */
3
4#pragma once
5#include <algorithm>
6#include <cassert>
7#include <cstddef>
8#include <stdio.h>
9#include <vector>
10
11namespace rapidfuzz {
12namespace detail {
13
14template <typename T, bool IsConst>
15struct BitMatrixView {
16
17 using value_type = T;
18 using size_type = size_t;
19 using pointer = typename std::conditional<IsConst, const value_type*, value_type*>::type;
20 using reference = typename std::conditional<IsConst, const value_type&, value_type&>::type;
21
22 BitMatrixView(pointer vector, size_type cols) noexcept : m_vector(vector), m_cols(cols)
23 {}
24
25 reference operator[](size_type col) noexcept
26 {
27 assert(col < m_cols);
28 return m_vector[col];
29 }
30
31 size_type size() const noexcept
32 {
33 return m_cols;
34 }
35
36private:
37 pointer m_vector;
38 size_type m_cols;
39};
40
41template <typename T>
42struct BitMatrix {
43
44 using value_type = T;
45
46 BitMatrix() : m_rows(0), m_cols(0), m_matrix(nullptr)
47 {}
48
49 BitMatrix(size_t rows, size_t cols, T val) : m_rows(rows), m_cols(cols), m_matrix(nullptr)
50 {
51 if (m_rows && m_cols) m_matrix = new T[m_rows * m_cols];
52 std::fill_n(m_matrix, m_rows * m_cols, val);
53 }
54
55 BitMatrix(const BitMatrix& other) : m_rows(other.m_rows), m_cols(other.m_cols), m_matrix(nullptr)
56 {
57 if (m_rows && m_cols) m_matrix = new T[m_rows * m_cols];
58 std::copy(other.m_matrix, other.m_matrix + m_rows * m_cols, m_matrix);
59 }
60
61 BitMatrix(BitMatrix&& other) noexcept : m_rows(0), m_cols(0), m_matrix(nullptr)
62 {
63 other.swap(*this);
64 }
65
66 BitMatrix& operator=(BitMatrix&& other) noexcept
67 {
68 other.swap(*this);
69 return *this;
70 }
71
72 BitMatrix& operator=(const BitMatrix& other)
73 {
74 BitMatrix temp = other;
75 temp.swap(*this);
76 return *this;
77 }
78
79 void swap(BitMatrix& rhs) noexcept
80 {
81 using std::swap;
82 swap(m_rows, rhs.m_rows);
83 swap(m_cols, rhs.m_cols);
84 swap(m_matrix, rhs.m_matrix);
85 }
86
87 ~BitMatrix()
88 {
89 delete[] m_matrix;
90 }
91
92 BitMatrixView<value_type, false> operator[](size_t row) noexcept
93 {
94 assert(row < m_rows);
95 return {&m_matrix[row * m_cols], m_cols};
96 }
97
98 BitMatrixView<value_type, true> operator[](size_t row) const noexcept
99 {
100 assert(row < m_rows);
101 return {&m_matrix[row * m_cols], m_cols};
102 }
103
104 size_t rows() const noexcept
105 {
106 return m_rows;
107 }
108
109 size_t cols() const noexcept
110 {
111 return m_cols;
112 }
113
114private:
115 size_t m_rows;
116 size_t m_cols;
117 T* m_matrix;
118};
119
120template <typename T>
121struct ShiftedBitMatrix {
122 using value_type = T;
123
124 ShiftedBitMatrix()
125 {}
126
127 ShiftedBitMatrix(size_t rows, size_t cols, T val) : m_matrix(rows, cols, val), m_offsets(rows)
128 {}
129
130 ShiftedBitMatrix(const ShiftedBitMatrix& other) : m_matrix(other.m_matrix), m_offsets(other.m_offsets)
131 {}
132
133 ShiftedBitMatrix(ShiftedBitMatrix&& other) noexcept
134 {
135 other.swap(*this);
136 }
137
138 ShiftedBitMatrix& operator=(ShiftedBitMatrix&& other) noexcept
139 {
140 other.swap(*this);
141 return *this;
142 }
143
144 ShiftedBitMatrix& operator=(const ShiftedBitMatrix& other)
145 {
146 ShiftedBitMatrix temp = other;
147 temp.swap(*this);
148 return *this;
149 }
150
151 void swap(ShiftedBitMatrix& rhs) noexcept
152 {
153 using std::swap;
154 swap(m_matrix, rhs.m_matrix);
155 swap(m_offsets, rhs.m_offsets);
156 }
157
158 bool test_bit(size_t row, size_t col, bool default_ = false) const noexcept
159 {
160 ptrdiff_t offset = m_offsets[row];
161
162 if (offset < 0) {
163 col += static_cast<size_t>(-offset);
164 }
165 else if (col >= static_cast<size_t>(offset)) {
166 col -= static_cast<size_t>(offset);
167 }
168 /* bit on the left of the band */
169 else {
170 return default_;
171 }
172
173 size_t word_size = sizeof(value_type) * 8;
174 size_t col_word = col / word_size;
175 value_type col_mask = value_type(1) << (col % word_size);
176
177 return bool(m_matrix[row][col_word] & col_mask);
178 }
179
180 BitMatrixView<value_type, false> operator[](size_t row) noexcept
181 {
182 return m_matrix[row];
183 }
184
185 BitMatrixView<value_type, true> operator[](size_t row) const noexcept
186 {
187 return m_matrix[row];
188 }
189
190 void set_offset(size_t row, ptrdiff_t offset)
191 {
192 m_offsets[row] = offset;
193 }
194
195private:
196 BitMatrix<value_type> m_matrix;
197 std::vector<ptrdiff_t> m_offsets;
198};
199
200} // namespace detail
201} // namespace rapidfuzz