fork download
  1. // Two-dimensional array with dimensions determined at compile-time
  2. //
  3. // Written in 2012 by Martinho Fernandes
  4. //
  5. // To the extent possible under law, the author(s) have dedicated all copyright and related
  6. // and neighboring rights to this software to the public domain worldwide. This software is
  7. // distributed without any warranty.
  8. //
  9. // You should have received a copy of the CC0 Public Domain Dedication along with this software.
  10. // If not, see <http://c...content-available-to-author-only...s.org/publicdomain/zero/1.0/>.
  11.  
  12. // Installation:
  13. // Place this into a header file and #include it in your code. Done.
  14. //
  15. // Usage:
  16. // so::sarray2d<int[10][10]> x; // create a 10x10 array
  17. // so::sarray2d<int[2][2]> y = {{ { 1, 2 }, { 3, 4 } }}; // initialize a 2x2 array (unfortunately it needs three levels of braces)
  18. // int x12 = x[1][2]; // access an element
  19. // x[1][2] = 42; // modify an element
  20. // int* all = x.data(); // get a pointer to the whole array
  21. // int* row1p = x[1].data(); // get a pointer to a row
  22. // std::sort(x.begin(), x.end()); // use the whole array in standard library algorithms
  23. // std::sort(x[1].begin(), x[1].end()); // use a row in standard library algorithms
  24. // so::sarray2d<int[10][10]> copy_of_x = x; // make a copy
  25. //
  26. // This can also be easily and safely returned from functions by value, no need to use pointers or dynamic allocation:
  27. // so::sarray2d<int[2][2]> get_an_array(int x) {
  28. // so::sarray2d<int[2][2]> result = {{ { x*1, x*2 }, { x*3, x*4 } }};
  29. // return result;
  30. // }
  31. //
  32. // Only two-dimensional arrays are supported.
  33. // If you think you need a three-dimensional array, you're probably doing
  34. // it wrong. But if you really want to take a stab at doing so, you may use
  35. // this code as a starting point.
  36. //
  37. // If you don't want any C++11 features #define SO_ARRAY2D_NO_CPP11 before #including.
  38. //
  39. // Now, go forth and stop using multidimensional C arrays!
  40.  
  41. #ifndef SO_SARRAY2D_HPP_INCLUDED
  42. #define SO_SARRAY2D_HPP_INCLUDED
  43.  
  44. #include <cassert> // assert
  45. #include <cstddef> // size_t, ptrdiff_t
  46.  
  47. #ifndef SO_ARRAY2D_NO_CPP11
  48. #define SO_ARRAY2D_CPP11_DELETE = delete
  49. #else
  50. #define SO_ARRAY2D_CPP11_DELETE
  51. #endif
  52.  
  53. namespace so {
  54. template <typename T>
  55. class sarray2d {
  56. #ifndef SO_ARRAY2D_NO_CPP11
  57. template <typename> struct bad_usage { enum { value = false }; };
  58. static_assert(bad_usage<T>::value, "You can only create an sarray2d with 2 dimensions, like so::sarray2d<int[2][3]>");
  59. #else
  60. struct bad_usage;
  61. bad_usage you_can_only_create_an_sarray2d_with_2_dimensions;
  62. #endif
  63. };
  64.  
  65. template <typename T, std::size_t N, std::size_t M>
  66. class sarray2d<T[N][M]> {
  67. public:
  68. class proxy {
  69. public:
  70. T& operator[](std::ptrdiff_t index) {
  71. assert(index >= 0 && index < M);
  72. return storage[row][index];
  73. }
  74. T* begin() { return &storage[row][0]; }
  75. T* end() { return &storage[row][0] + M; }
  76. T* data() { return &storage[row][0]; }
  77.  
  78. private:
  79. template <typename X>
  80. void operator=(X const&) SO_ARRAY2D_CPP11_DELETE;
  81.  
  82. friend class sarray2d<T[N][M]>;
  83.  
  84. proxy(T (&storage)[N][M], std::ptrdiff_t row)
  85. : storage(storage), row(row) {}
  86.  
  87. T (&storage)[N][M];
  88. std::ptrdiff_t row;
  89. };
  90.  
  91. class const_proxy {
  92. public:
  93. T const& operator[](std::ptrdiff_t index) {
  94. assert(index >= 0 && index < M);
  95. return storage[row][index];
  96. }
  97. T const* begin() const { return &storage[row][0]; }
  98. T const* end() const { return &storage[row][0] + M; }
  99. T const* data() const { return &storage[row][0]; }
  100.  
  101. private:
  102. template <typename X>
  103. void operator=(X const&) SO_ARRAY2D_CPP11_DELETE;
  104.  
  105. friend class sarray2d<T[N][M]>;
  106.  
  107. const_proxy(T const (&storage)[N][M], std::ptrdiff_t row)
  108. : storage(storage), row(row) {}
  109.  
  110. T const (&storage)[N][M];
  111. std::ptrdiff_t row;
  112. };
  113.  
  114. proxy operator[](std::ptrdiff_t index) {
  115. assert(index >= 0 && index < N);
  116. return proxy(storage, index);
  117. }
  118. const_proxy operator[](std::ptrdiff_t index) const {
  119. assert(index >= 0 && index < N);
  120. return const_proxy(storage, index);
  121. }
  122.  
  123. T* begin() { return &storage[0][0]; }
  124. T* end() { return &storage[0][0] + N*M; }
  125. T* data() { return &storage[0][0]; }
  126. T const* begin() const { return &storage[0][0]; }
  127. T const* end() const { return &storage[0][0] + N*M; }
  128. T const* data() const { return &storage[0][0]; }
  129.  
  130. T storage[N][M]; // public only to facilitate aggregate construction
  131. // do not use directly
  132. };
  133. }
  134.  
  135. #undef SO_ARRAY2D_CPP11_DELETE
  136.  
  137. #endif
  138.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty