1 // license:GPL-2.0+ 2 // copyright-holders:Couriersud 3 4 #ifndef PMATRIX2D_H_ 5 #define PMATRIX2D_H_ 6 7 /// 8 /// \file pmatrix2d.h 9 /// 10 11 #include "palloc.h" 12 13 #include <algorithm> 14 #include <type_traits> 15 #include <vector> 16 17 namespace plib 18 { 19 20 template<typename T, typename A = aligned_arena> 21 class pmatrix2d 22 { 23 public: 24 using size_type = std::size_t; 25 using arena_type = A; 26 using allocator_type = typename A::template allocator_type<T, PALIGN_VECTOROPT>; 27 28 static constexpr const size_type align_size = align_traits<allocator_type>::align_size; 29 static constexpr const size_type stride_size = align_traits<allocator_type>::stride_size; 30 31 using value_type = T; 32 using reference = T &; 33 using const_reference = const T &; 34 35 using pointer = T *; 36 using const_pointer = const T *; 37 pmatrix2d()38 pmatrix2d() noexcept 39 : m_N(0), m_M(0), m_stride(8), m_v(nullptr) 40 { 41 } 42 pmatrix2d(size_type N,size_type M)43 pmatrix2d(size_type N, size_type M) 44 : m_N(N), m_M(M), m_v() 45 { 46 gsl_Expects(N>0); 47 gsl_Expects(M>0); 48 m_stride = ((M + stride_size-1) / stride_size) * stride_size; 49 m_v = m_a.allocate(N * m_stride); 50 for (std::size_t i = 0; i < N * m_stride; i++) 51 ::new(&m_v[i]) T(); 52 } 53 54 pmatrix2d(const pmatrix2d &) = delete; 55 pmatrix2d &operator=(const pmatrix2d &) = delete; 56 pmatrix2d(pmatrix2d &&) = delete; 57 pmatrix2d &operator=(pmatrix2d &&) = delete; 58 ~pmatrix2d()59 ~pmatrix2d() 60 { 61 if (m_v != nullptr) 62 { 63 for (std::size_t i = 0; i < m_N * m_stride; i++) 64 (&m_v[i])->~T(); 65 m_a.deallocate(m_v, m_N * m_stride); 66 } 67 } 68 resize(size_type N,size_type M)69 void resize(size_type N, size_type M) 70 { 71 gsl_Expects(N>0); 72 gsl_Expects(M>0); 73 if (m_v != nullptr) 74 { 75 for (std::size_t i = 0; i < N * m_stride; i++) 76 (&m_v[i])->~T(); 77 m_a.deallocate(m_v, N * m_stride); 78 } 79 m_N = N; 80 m_M = M; 81 m_stride = ((M + stride_size-1) / stride_size) * stride_size; 82 m_v = m_a.allocate(N * m_stride); 83 for (std::size_t i = 0; i < N * m_stride; i++) 84 ::new(&m_v[i]) T(); 85 } 86 87 constexpr pointer operator[] (size_type row) noexcept 88 { 89 return &m_v[m_stride * row]; 90 } 91 92 constexpr const_pointer operator[] (size_type row) const noexcept 93 { 94 return &m_v[m_stride * row]; 95 } 96 operator()97 reference operator()(size_type r, size_type c) noexcept 98 { 99 return (*this)[r][c]; 100 } 101 operator()102 const_reference operator()(size_type r, size_type c) const noexcept 103 { 104 return (*this)[r][c]; 105 } 106 107 // for compatibility with vrl variant set(size_type r,size_type c,const value_type & v)108 void set(size_type r, size_type c, const value_type &v) noexcept 109 { 110 (*this)[r][c] = v; 111 } 112 data()113 pointer data() noexcept 114 { 115 return m_v; 116 } 117 data()118 const_pointer data() const noexcept 119 { 120 return m_v; 121 } 122 didx(size_type r,size_type c)123 size_type didx(size_type r, size_type c) const noexcept 124 { 125 return m_stride * r + c; 126 } 127 private: 128 129 size_type m_N; 130 size_type m_M; 131 size_type m_stride; 132 133 T * __restrict m_v; 134 135 allocator_type m_a; 136 }; 137 138 // variable row length matrix 139 template<typename T, typename A = aligned_arena> 140 class pmatrix2d_vrl 141 { 142 public: 143 using size_type = std::size_t; 144 using value_type = T; 145 using arena_type = A; 146 using allocator_type = typename A::template allocator_type<T, PALIGN_VECTOROPT>; 147 148 static constexpr const size_type align_size = align_traits<allocator_type>::align_size; 149 static constexpr const size_type stride_size = align_traits<allocator_type>::stride_size; 150 pmatrix2d_vrl()151 pmatrix2d_vrl() noexcept 152 : m_N(0), m_M(0), m_v() 153 { 154 } 155 pmatrix2d_vrl(size_type N,size_type M)156 pmatrix2d_vrl(size_type N, size_type M) 157 : m_N(N), m_M(M), m_v() 158 { 159 m_row.resize(N + 1, 0); 160 m_v.resize(N); //FIXME 161 } 162 163 pmatrix2d_vrl(const pmatrix2d_vrl &) = default; 164 pmatrix2d_vrl &operator=(const pmatrix2d_vrl &) = default; 165 pmatrix2d_vrl(pmatrix2d_vrl &&) = default; 166 pmatrix2d_vrl &operator=(pmatrix2d_vrl &&) = default; 167 168 ~pmatrix2d_vrl() = default; 169 resize(size_type N,size_type M)170 void resize(size_type N, size_type M) 171 { 172 m_N = N; 173 m_M = M; 174 m_row.resize(N + 1); 175 for (std::size_t i = 0; i < m_N; i++) 176 m_row[i] = 0; 177 m_v.resize(N); //FIXME 178 } 179 180 constexpr T * operator[] (size_type row) noexcept 181 { 182 return &(m_v[m_row[row]]); 183 } 184 185 constexpr const T * operator[] (size_type row) const noexcept 186 { 187 return &(m_v[m_row[row]]); 188 } 189 190 //FIXME: no check! operator()191 T & operator()(size_type r, size_type c) noexcept 192 { 193 return (*this)[r][c]; 194 } 195 set(size_type r,size_type c,const T & v)196 void set(size_type r, size_type c, const T &v) noexcept 197 { 198 if (c + m_row[r] >= m_row[r + 1]) 199 { 200 m_v.insert(m_v.begin() + narrow_cast<std::ptrdiff_t>(m_row[r+1]), v); 201 for (size_type i = r + 1; i <= m_N; i++) 202 m_row[i] = m_row[i] + 1; 203 } 204 else 205 (*this)[r][c] = v; 206 } 207 208 //FIXME: no check! operator()209 const T & operator()(size_type r, size_type c) const noexcept 210 { 211 return (*this)[r][c]; 212 } 213 data()214 T * data() noexcept 215 { 216 return m_v.data(); 217 } 218 data()219 const T * data() const noexcept 220 { 221 return m_v.data(); 222 } 223 224 //FIXME: no check! didx(size_type r,size_type c)225 size_type didx(size_type r, size_type c) const noexcept 226 { 227 return m_row[r] + c; 228 } 229 colcount(size_type row)230 size_type colcount(size_type row) const noexcept 231 { 232 return m_row[row + 1] - m_row[row]; 233 } 234 tx()235 size_type tx() const { return m_v.size(); } 236 private: 237 238 size_type m_N; 239 size_type m_M; 240 std::vector<size_type, typename A::template allocator_type<size_type>> m_row; 241 std::vector<T, allocator_type> m_v; 242 }; 243 244 245 } // namespace plib 246 247 #endif // PMATRIX2D_H_ 248