fork download
  1. #include <iostream>
  2. #include <vector>
  3. #include <initializer_list>
  4. #include <utility>
  5.  
  6. namespace stdx {
  7.  
  8. template <typename T, typename Allocator>
  9. class matrix;
  10.  
  11. template<typename T, typename Allocator = std::allocator<T>>
  12. class matrix_helper {
  13. public:
  14. friend class matrix<T, Allocator>;
  15.  
  16. using o_matrix = matrix<T, Allocator>;
  17. using p_vector = std::vector<T, Allocator>;
  18. using v_size_t = typename p_vector::size_type;
  19.  
  20. typename p_vector::reference operator [] (v_size_t colindex) {
  21. return static_cast<p_vector &>(matrix_)[rowindex_ * matrix_.rowsize() + colindex];
  22. }
  23.  
  24. operator typename p_vector::reference () {
  25. return static_cast<p_vector &>(matrix_)[rowindex_];
  26. }
  27.  
  28. typename p_vector::reference operator = (T &&value) {
  29. return (typename p_vector::reference)(*this) = std::forward<T>(value);
  30. }
  31.  
  32. protected:
  33. matrix_helper(o_matrix &matrix, v_size_t rowindex) :
  34. matrix_(matrix),
  35. rowindex_(rowindex)
  36. {}
  37.  
  38. protected:
  39. o_matrix &matrix_;
  40. v_size_t rowindex_;
  41. };
  42.  
  43. template<typename T, typename Allocator = std::allocator<T>>
  44. class const_matrix_helper : public matrix_helper<T, Allocator> {
  45. public:
  46. friend class matrix<T, Allocator>;
  47.  
  48. using o_matrix = matrix<T, Allocator>;
  49. using p_vector = std::vector<T, Allocator>;
  50. using v_size_t = typename p_vector::size_type;
  51.  
  52. typename p_vector::const_reference operator [] (v_size_t colindex) const {
  53. return const_cast<matrix_helper<T, Allocator> *>(this)->operator [](colindex);
  54. }
  55.  
  56. operator typename p_vector::const_reference () const {
  57. return (typename p_vector::reference) const_cast<matrix_helper<T, Allocator> *>(this);
  58. }
  59.  
  60. protected:
  61. const_matrix_helper(const o_matrix &matrix, v_size_t rowindex) :
  62. matrix_helper<T, Allocator>(const_cast<o_matrix &>(matrix), rowindex)
  63. {}
  64. };
  65.  
  66. template <typename T, typename Allocator = std::allocator<T>>
  67. class matrix : public std::vector<T, Allocator> {
  68. public:
  69. using p_vector = std::vector<T, Allocator>;
  70. using v_size_t = typename p_vector::size_type;
  71.  
  72. matrix(std::initializer_list<std::initializer_list<T>> contents)
  73. {
  74. for (auto &row : contents) {
  75. rowsize_ = row.size();
  76. p_vector::insert(p_vector::end(), row);
  77. }
  78. }
  79.  
  80. matrix(typename p_vector::size_type rowsize, std::initializer_list<T> contents) :
  81. p_vector(contents),
  82. rowsize_(rowsize)
  83. {}
  84.  
  85. v_size_t rowsize() const {
  86. return rowsize_;
  87. }
  88.  
  89. v_size_t colsize() const {
  90. return p_vector::size() / rowsize_;
  91. }
  92.  
  93. const const_matrix_helper<T, Allocator> operator [] (v_size_t rowindex) const {
  94. return const_matrix_helper<T, Allocator>(*this, rowindex);
  95. }
  96.  
  97. matrix_helper<T, Allocator> operator [] (v_size_t rowindex) {
  98. return matrix_helper<T, Allocator>(*this, rowindex);
  99. }
  100.  
  101. private:
  102. static constexpr v_size_t invalid_size = -1;
  103. v_size_t rowsize_ = invalid_size;
  104. };
  105.  
  106. }
  107.  
  108. using std::cout;
  109. using std::endl;
  110.  
  111. int main(int argc, char *argv[])
  112. {
  113. (void) argc;
  114. (void) argv;
  115.  
  116. stdx::matrix<int> m0 = {
  117. { 1, 2, 3 },
  118. { 4, 5, 6 },
  119. { 7, 8, 9 }
  120. };
  121.  
  122. cout << "m0[1, 2] = " << m0[1][2] << endl;
  123. cout << "m0[1] = " << (int) m0[1] << endl;
  124.  
  125. m0[1][2] = 42;
  126. m0[1] = 3;
  127.  
  128. cout << "After change:\n" << endl;
  129. cout << "m0[1, 2] = " << m0[1][2] << endl;
  130. cout << "m0[1] = " << (int) m0[1] << endl;
  131.  
  132. stdx::matrix<int> m1(2, { 1, 2, 3, 4 });
  133.  
  134. return 0;
  135. }
  136.  
Success #stdin #stdout 0s 3416KB
stdin
Standard input is empty
stdout
m0[1, 2] = 6
m0[1] = 2
After change:

m0[1, 2] = 42
m0[1] = 3