fork download
  1. #include <array>
  2. #include <cassert>
  3. #include <iostream>
  4. #include <map>
  5. #include <stdexcept>
  6.  
  7. template <typename T>
  8. class SparseMatrix;
  9.  
  10. template <typename T>
  11. class SparseMatrixProxy {
  12. SparseMatrix<T> &matrix;
  13. const std::array<int, 2> indices;
  14.  
  15. public:
  16. SparseMatrixProxy(SparseMatrix<T> &matrix, const std::array<int, 2> indices)
  17. : matrix{matrix}
  18. , indices{indices} {}
  19. //for reading an element:
  20. operator T() const {
  21. // Check if given indices are within the size of the matrix
  22. if (indices[0] >= matrix.size[0] || indices[1] >= matrix.size[1])
  23. throw std::invalid_argument("Indices out of bounds");
  24. auto map_it = matrix.data.find(indices);
  25. if (map_it == matrix.data.end()) {
  26. return T{};
  27. }
  28. return map_it->second;
  29. }
  30. //for writing an element:
  31. auto operator=(const T &t) {
  32. //optional: when setting a value to 0 erase it from the map
  33. if (t == T{}) {
  34. matrix.data.erase(indices);
  35. } else {
  36. matrix.data[indices] = t;
  37. }
  38. return *this;
  39. }
  40. };
  41.  
  42. template <typename T>
  43. class SparseMatrix {
  44. std::map<std::array<int, 2>, T> data;
  45. const std::array<int, 2> size;
  46.  
  47. public:
  48. SparseMatrix(const int rows, const int cols)
  49. : size({{rows, cols}}) {}
  50.  
  51. // []-operator to set and get values from matrix
  52. SparseMatrixProxy<T> operator[](const std::array<int, 2> indices) {
  53. return {*this, indices};
  54. }
  55. auto mapsize() const {
  56. return data.size();
  57. }
  58. friend class SparseMatrixProxy<T>;
  59. };
  60.  
  61. int main() {
  62. SparseMatrix<double> M(2, 2); // Create a new sparse matrix with 2 rows and 2 columns
  63. M[{{1, 1}}] = 3.1; // Sets element {1,1} to 3.1
  64. std::cout << M[{{1, 1}}] << '\n';
  65. assert(M.mapsize() == 1); //1 element for index {1,1}
  66. std::cout << M[{{0, 0}}] << '\n';
  67. assert(M.mapsize() == 1); //still 1 element because reading doesn't insert an element
  68. M[{{1, 1}}] = 0;
  69. assert(M.mapsize() == 0); //0 elements because we set the only non-0 element to 0
  70. }
  71.  
Success #stdin #stdout 0s 16056KB
stdin
Standard input is empty
stdout
3.1
0