2d_array.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #pragma once
  2. #include <util/system/yassert.h>
  3. #include <util/generic/algorithm.h>
  4. // FIXME: check for Y_IF_DEBUG instead
  5. #ifdef _DEBUG
  6. template <class T>
  7. struct TBoundCheck {
  8. T* Data;
  9. size_t Size;
  10. TBoundCheck(T* d, size_t s) {
  11. Data = d;
  12. Size = s;
  13. }
  14. T& operator[](size_t i) const {
  15. Y_ASSERT(i >= 0 && i < Size);
  16. return Data[i];
  17. }
  18. };
  19. #endif
  20. template <class T>
  21. class TArray2D {
  22. private:
  23. typedef T* PT;
  24. T* Data;
  25. T** PData;
  26. size_t XSize;
  27. size_t YSize;
  28. private:
  29. void Copy(const TArray2D& a) {
  30. XSize = a.XSize;
  31. YSize = a.YSize;
  32. Create();
  33. for (size_t i = 0; i < XSize * YSize; i++)
  34. Data[i] = a.Data[i];
  35. }
  36. void Destroy() {
  37. delete[] Data;
  38. delete[] PData;
  39. }
  40. void Create() {
  41. Data = new T[XSize * YSize];
  42. PData = new PT[YSize];
  43. for (size_t i = 0; i < YSize; i++)
  44. PData[i] = Data + i * XSize;
  45. }
  46. public:
  47. TArray2D(size_t xsize = 1, size_t ysize = 1) {
  48. XSize = xsize;
  49. YSize = ysize;
  50. Create();
  51. }
  52. TArray2D(const TArray2D& a) {
  53. Copy(a);
  54. }
  55. TArray2D& operator=(const TArray2D& a) {
  56. Destroy();
  57. Copy(a);
  58. return *this;
  59. }
  60. ~TArray2D() {
  61. Destroy();
  62. }
  63. void SetSizes(size_t xsize, size_t ysize) {
  64. if (XSize == xsize && YSize == ysize)
  65. return;
  66. Destroy();
  67. XSize = xsize;
  68. YSize = ysize;
  69. Create();
  70. }
  71. void Clear() {
  72. SetSizes(1, 1);
  73. }
  74. #ifdef _DEBUG
  75. TBoundCheck<T> operator[](size_t i) const {
  76. Y_ASSERT(i < YSize);
  77. return TBoundCheck<T>(PData[i], XSize);
  78. }
  79. #else
  80. T* operator[](size_t i) const {
  81. Y_ASSERT(i < YSize);
  82. return PData[i];
  83. }
  84. #endif
  85. size_t GetXSize() const {
  86. return XSize;
  87. }
  88. size_t GetYSize() const {
  89. return YSize;
  90. }
  91. void FillZero() {
  92. memset(Data, 0, sizeof(T) * XSize * YSize);
  93. }
  94. void FillEvery(const T& a) {
  95. for (size_t i = 0; i < XSize * YSize; i++)
  96. Data[i] = a;
  97. }
  98. void Swap(TArray2D& a) {
  99. std::swap(Data, a.Data);
  100. std::swap(PData, a.PData);
  101. std::swap(XSize, a.XSize);
  102. std::swap(YSize, a.YSize);
  103. }
  104. };
  105. template <class T>
  106. inline bool operator==(const TArray2D<T>& a, const TArray2D<T>& b) {
  107. if (a.GetXSize() != b.GetXSize() || a.GetYSize() != b.GetYSize())
  108. return false;
  109. for (size_t y = 0; y < a.GetYSize(); ++y) {
  110. for (size_t x = 0; x < a.GetXSize(); ++x)
  111. if (a[y][x] != b[y][x])
  112. return false;
  113. }
  114. return true;
  115. }
  116. template <class T>
  117. inline bool operator!=(const TArray2D<T>& a, const TArray2D<T>& b) {
  118. return !(a == b);
  119. }