Skip to content

Instantly share code, notes, and snippets.

@grayed
Created May 8, 2024 10:24
Show Gist options
  • Save grayed/1f83cb7d9d01b7df595240e6bca4aefc to your computer and use it in GitHub Desktop.
Save grayed/1f83cb7d9d01b7df595240e6bca4aefc to your computer and use it in GitHub Desktop.
Lazy copying (invalid)
#include <climits>
#include <iostream>
#include <cstring>
#include <new>
using namespace std;
class Matrix {
struct MatrixData {
double *nums;
size_t nrows, ncols;
int nrefs;
MatrixData(size_t nrows, size_t ncols) : nrows(nrows), ncols(ncols), nrefs(1) {
cerr << "created MatrixData " << nrows << "x" << ncols << ": 0x" << hex << (intptr_t)this << endl;
if (ncols >= SIZE_MAX / sizeof(double))
throw out_of_range("too large columns count");
nums = static_cast<double*>(calloc(nrows, ncols * sizeof(double)));
if (!nums)
throw bad_alloc();
}
void addreference() {
cerr << "addref for MatrixData: 0x" << hex << (intptr_t)this << endl;
nrefs++;
}
void dereference() {
cerr << "dereferenced MatrixData: 0x" << hex << (intptr_t)this << endl;
if (!--nrefs) { delete nums; delete this; }
}
} *d;
public:
/// https://gist.github.com/grayed/
/// 1. Реализовать методы для получения и перезаписи строки и столбца из vector<double>.
/// 2. Реализовать ленивое копирование (с подсчётом ссылок).
Matrix(size_t nrows, size_t ncols) : d(new MatrixData(nrows, ncols)) {}
Matrix(const Matrix &m) : d(m.d) { d->addreference(); }
~Matrix() { cerr << "!destructor " << (intptr_t)d->nums << "!"; d->dereference(); }
Matrix& operator=(const Matrix &m) {
d->dereference();
d = m.d;
d->addreference();
return *this;
}
double& operator()(size_t row, size_t col) {
cerr << '(' << (intptr_t)this << ')';
if (row >= d->nrows)
throw out_of_range("invalid row index");
if (col >= d->ncols)
throw out_of_range("invalid column index");
return d->nums[row * d->ncols + col];
}
double operator()(size_t row, size_t col) const {
cerr << '[' << (intptr_t)this << ']';
if (row >= d->nrows)
throw out_of_range("invalid row");
if (col >= d->ncols)
throw out_of_range("invalid column index");
return d->nums[row * d->ncols + col];
}
Matrix operator*(double n) const {
Matrix m(d->nrows, d->ncols);
for (size_t row = 0; row < d->nrows; row++)
for (size_t col = 0; col < d->ncols; col++)
m(row, col) = (*this)(row, col) * n;
return m;
}
friend ostream& operator<<(ostream &os, const Matrix &m);
};
ostream& operator<<(ostream &os, const Matrix &m) {
for (size_t row = 0; row < m.d->nrows; row++) {
for (size_t col = 0; col < m.d->ncols; col++)
os << m(row, col) << ' ';
os << endl;
}
return os;
}
int main()
{
Matrix m1(5, 5); m1(0, 0) = 1; m1(0, 1) = 2; m1(1, 0) = 3; m1(1, 1) = -0.5;
cout << m1 << endl;
Matrix m2 = m1 * -1.3;
cout << m2 << endl;
Matrix m3(5, 5);
m3 = m2;
cout << m3 << endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment