fork download
  1. #include <iostream>
  2. #include <array>
  3. #include <vector>
  4. #include <type_traits>
  5. #include <initializer_list>
  6. #include <algorithm>
  7. #include <numeric>
  8. #include <tuple>
  9.  
  10. template<typename... Values>
  11. using IsCorrectIndicies_t = std::tuple<std::enable_if_t<std::is_integral<Values>::value>...>;
  12.  
  13. template <typename T, size_t... Dimensions>
  14. class Matrix
  15. {
  16. public:
  17. Matrix()
  18. {
  19. std::array<size_t, sizeof...(Dimensions)> dimensions{Dimensions...};
  20. size_t size = std::accumulate(dimensions.begin(), dimensions.end(), size_t{1}, std::multiplies<>{});
  21. m_Container.resize(size);
  22. }
  23.  
  24. template<typename... Values, typename = IsCorrectIndicies_t<Values...>>
  25. T& At(Values... indicies)
  26. {
  27. static_assert(sizeof...(indicies) == sizeof...(Dimensions), "Dimensions don't match!");
  28. std::array<size_t, sizeof...(indicies)> input{static_cast<size_t>(indicies)...};
  29. std::array<size_t, sizeof...(indicies)> dimensions{Dimensions...};
  30. for(size_t i = 0; i < input.size(); ++i)
  31. {
  32. if(input[i] >= dimensions[i])
  33. throw std::runtime_error{"Wrong indicies"};
  34. }
  35. return _getElement(input);
  36. }
  37. private:
  38. T& _getElement(const std::array<size_t, sizeof...(Dimensions)>& indicies)
  39. {
  40. return m_Container[_calculateIndex(indicies)];
  41. }
  42.  
  43. size_t _calculateIndex(const std::array<size_t, sizeof...(Dimensions)>& indicies)
  44. {
  45. std::array<size_t, sizeof...(Dimensions)> dimensions{Dimensions...};
  46. size_t internalIndex = 0;
  47. for(size_t i = 0; i < indicies.size(); ++i)
  48. {
  49. auto span = std::accumulate(dimensions.begin() + i + 1, dimensions.end(), indicies[i],
  50. std::multiplies<>{});
  51. internalIndex += span;
  52. }
  53. return internalIndex;
  54. }
  55. private:
  56. std::vector<T> m_Container;
  57. };
  58.  
  59.  
  60. int main(int argc, char* argv[])
  61. {
  62. constexpr size_t columns = 8;
  63. constexpr size_t rows = 8;
  64. Matrix<double, rows, columns> M3{};
  65. for(size_t i = 0; i < rows; ++i)
  66. for(size_t j = 0; j < columns; ++j)
  67. M3.At(i, j) = j + columns*i;
  68. for(size_t i = 0; i < rows; ++i)
  69. for(size_t j = 0; j < columns; ++j)
  70. {
  71. std::cout << "array(" << i << "," << j << ") = "
  72. << M3.At(i, j) << "\n";
  73. }
  74. return 0;
  75. }
Success #stdin #stdout 0s 3468KB
stdin
Standard input is empty
stdout
array(0,0) = 0
array(0,1) = 1
array(0,2) = 2
array(0,3) = 3
array(0,4) = 4
array(0,5) = 5
array(0,6) = 6
array(0,7) = 7
array(1,0) = 8
array(1,1) = 9
array(1,2) = 10
array(1,3) = 11
array(1,4) = 12
array(1,5) = 13
array(1,6) = 14
array(1,7) = 15
array(2,0) = 16
array(2,1) = 17
array(2,2) = 18
array(2,3) = 19
array(2,4) = 20
array(2,5) = 21
array(2,6) = 22
array(2,7) = 23
array(3,0) = 24
array(3,1) = 25
array(3,2) = 26
array(3,3) = 27
array(3,4) = 28
array(3,5) = 29
array(3,6) = 30
array(3,7) = 31
array(4,0) = 32
array(4,1) = 33
array(4,2) = 34
array(4,3) = 35
array(4,4) = 36
array(4,5) = 37
array(4,6) = 38
array(4,7) = 39
array(5,0) = 40
array(5,1) = 41
array(5,2) = 42
array(5,3) = 43
array(5,4) = 44
array(5,5) = 45
array(5,6) = 46
array(5,7) = 47
array(6,0) = 48
array(6,1) = 49
array(6,2) = 50
array(6,3) = 51
array(6,4) = 52
array(6,5) = 53
array(6,6) = 54
array(6,7) = 55
array(7,0) = 56
array(7,1) = 57
array(7,2) = 58
array(7,3) = 59
array(7,4) = 60
array(7,5) = 61
array(7,6) = 62
array(7,7) = 63