|
11 | 11 | */ |
12 | 12 | #pragma once |
13 | 13 |
|
| 14 | +#include <algorithm> |
| 15 | +#include <cstddef> |
| 16 | + |
14 | 17 | namespace GauXC::detail { |
15 | 18 |
|
16 | 19 | class CMatrix { |
17 | 20 | public: |
18 | 21 | using value_type = double; |
19 | | - CMatrix( ) noexcept : rows_(0), cols_(0), data_(nullptr) {} |
20 | | - CMatrix( size_t rows, size_t cols ) noexcept { |
21 | | - rows_ = rows; |
22 | | - cols_ = cols; |
23 | | - data_ = new value_type[ rows * cols ](); |
24 | | - } |
| 22 | + |
| 23 | + /** |
| 24 | + * @brief Default constructor creates a 0x0 matrix |
| 25 | + */ |
| 26 | + CMatrix() noexcept : rows_(0), cols_(0), data_(nullptr) {} |
| 27 | + |
| 28 | + /** |
| 29 | + * @brief Construct a new CMatrix object |
| 30 | + * @param rows Number of rows |
| 31 | + * @param cols Number of columns |
| 32 | + */ |
| 33 | + CMatrix(size_t rows, size_t cols) |
| 34 | + : rows_(rows), cols_(cols), data_(new value_type[rows * cols]()) {} |
| 35 | + |
| 36 | + /** |
| 37 | + * @brief Destroy the CMatrix object |
| 38 | + */ |
25 | 39 | ~CMatrix() noexcept { |
26 | | - if (data_) delete[] data_; |
27 | | - data_ = nullptr; |
| 40 | + delete[] data_; // delete[] on nullptr is safe |
| 41 | + } |
| 42 | + |
| 43 | + /** |
| 44 | + * @brief Copy constructor |
| 45 | + * @param other CMatrix to copy from |
| 46 | + */ |
| 47 | + CMatrix(const CMatrix& other) |
| 48 | + : rows_(other.rows_), cols_(other.cols_), data_(nullptr) { |
| 49 | + if (other.data_ && rows_ * cols_ > 0) { |
| 50 | + data_ = new value_type[rows_ * cols_]; |
| 51 | + std::copy(other.data_, other.data_ + rows_ * cols_, data_); |
| 52 | + } |
28 | 53 | } |
29 | | - value_type * data() noexcept { return data_; } |
30 | | - const value_type * data() const noexcept { return data_; } |
| 54 | + |
| 55 | + /** |
| 56 | + * @brief Copy assignment operator |
| 57 | + * @param other CMatrix to copy from |
| 58 | + * @return CMatrix& Reference to this |
| 59 | + */ |
| 60 | + CMatrix& operator=(const CMatrix& other) { |
| 61 | + if (this != &other) { |
| 62 | + // Always clean up if sizes differ OR if other has no data |
| 63 | + if (rows_ * cols_ != other.rows_ * other.cols_ || !other.data_) { |
| 64 | + delete[] data_; |
| 65 | + data_ = nullptr; |
| 66 | + } |
| 67 | + rows_ = other.rows_; |
| 68 | + cols_ = other.cols_; |
| 69 | + if (other.data_ && rows_ * cols_ > 0) { |
| 70 | + if (!data_) { |
| 71 | + data_ = new value_type[rows_ * cols_]; |
| 72 | + } |
| 73 | + std::copy(other.data_, other.data_ + rows_ * cols_, data_); |
| 74 | + } |
| 75 | + } |
| 76 | + return *this; |
| 77 | + } |
| 78 | + |
| 79 | + /** |
| 80 | + * @brief Move constructor |
| 81 | + * @param other CMatrix to move from |
| 82 | + */ |
| 83 | + CMatrix(CMatrix&& other) noexcept |
| 84 | + : rows_(other.rows_), cols_(other.cols_), data_(other.data_) { |
| 85 | + other.rows_ = 0; |
| 86 | + other.cols_ = 0; |
| 87 | + other.data_ = nullptr; |
| 88 | + } |
| 89 | + |
| 90 | + // Move assignment |
| 91 | + /** |
| 92 | + * @brief Move assignment operator |
| 93 | + * @param other CMatrix to move from |
| 94 | + * @return CMatrix& Reference to this |
| 95 | + */ |
| 96 | + CMatrix& operator=(CMatrix&& other) noexcept { |
| 97 | + if (this != &other) { |
| 98 | + delete[] data_; |
| 99 | + rows_ = other.rows_; |
| 100 | + cols_ = other.cols_; |
| 101 | + data_ = other.data_; |
| 102 | + other.rows_ = 0; |
| 103 | + other.cols_ = 0; |
| 104 | + other.data_ = nullptr; |
| 105 | + } |
| 106 | + return *this; |
| 107 | + } |
| 108 | + |
| 109 | + /** |
| 110 | + * @brief Get pointer to raw data |
| 111 | + * @return value_type* Pointer to data |
| 112 | + */ |
| 113 | + value_type* data() noexcept { return data_; } |
| 114 | + /** |
| 115 | + * @brief Get pointer to raw data (const) |
| 116 | + * @return const value_type* Pointer to data |
| 117 | + */ |
| 118 | + const value_type* data() const noexcept { return data_; } |
| 119 | + /** |
| 120 | + * @brief Get number of rows |
| 121 | + * @return size_t Number of rows |
| 122 | + */ |
31 | 123 | size_t rows() const noexcept { return rows_; } |
| 124 | + /** |
| 125 | + * @brief Get number of columns |
| 126 | + * @return size_t Number of columns |
| 127 | + */ |
32 | 128 | size_t cols() const noexcept { return cols_; } |
| 129 | + |
| 130 | + /** |
| 131 | + * @brief Set all elements to zero |
| 132 | + */ |
33 | 133 | void setZero() noexcept { |
34 | | - for( size_t i = 0; i < rows_ * cols_; ++i ) |
| 134 | + for (size_t i = 0; i < rows_ * cols_; ++i) |
35 | 135 | data_[i] = value_type(0); |
36 | 136 | } |
37 | | - void resize( size_t rows, size_t cols ) noexcept { |
38 | | - if( rows == rows_ && cols == cols_ ) return; |
39 | | - if (data_) delete[] data_; |
| 137 | + |
| 138 | + /** |
| 139 | + * @brief Resize the matrix |
| 140 | + * @param rows New number of rows |
| 141 | + * @param cols New number of columns |
| 142 | + */ |
| 143 | + void resize(size_t rows, size_t cols) { |
| 144 | + if (rows == rows_ && cols == cols_) return; |
| 145 | + delete[] data_; |
40 | 146 | rows_ = rows; |
41 | 147 | cols_ = cols; |
42 | | - data_ = new value_type[ rows * cols ](); |
| 148 | + data_ = new value_type[rows * cols](); |
43 | 149 | } |
44 | 150 |
|
45 | 151 | private: |
46 | | - size_t rows_; |
47 | | - size_t cols_; |
48 | | - value_type* data_; |
| 152 | + size_t rows_ = 0; |
| 153 | + size_t cols_ = 0; |
| 154 | + value_type* data_ = nullptr; |
49 | 155 | }; |
50 | 156 |
|
51 | 157 | static inline CMatrix* get_matrix_ptr(C::GauXCMatrix matrix) noexcept { |
|
0 commit comments