Guest User

Untitled

a guest
Nov 17th, 2017
2,619
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.41 KB | None | 0 0
  1. /*
  2. Written by Chris Pikul <ChrisPikul510@gmail.com>
  3. */
  4. #pragma once
  5.  
  6. #include <memory>
  7. #include <algorithm>
  8.  
  9. /**
  10. Represents a 2 dimensional array of given type <T>
  11. Provides helper functions for getting and setting values.
  12.  
  13. Example:
  14. [code]
  15. Array2D<int> array(100,50); //Create array with 100 wide, and 50 high
  16. array.setValue(3, 50, 40); //Set value at 50,40 to 3
  17. int val = array.getValue(50, 40); //Returns value at 50,40 being 3 in this ex.
  18.  
  19. array[42] = 123; //Can also set individual indexes
  20. array(3, 50, 40); //Can set using short-hand functor
  21. val = array(50,40); //Use the shorter-hand functor to get a value as well
  22.  
  23. array.setValueClamped(3, 120, 70); //Protective clamp function keeps in range
  24. array.setValueWrapped(3, 120, 70); //Protective wrap function wraps around into valid indice
  25. [/code]
  26. */
  27. template<class T> struct Array2D{
  28. /**
  29. Construct an array with the given square size.
  30. Both the X, and Y indices will be the same
  31. */
  32. Array2D(unsigned int initialSize) {
  33. this->sizeX = initialSize;
  34. this->sizeY = initialSize;
  35. this->data = new T[sizeX * sizeY];
  36. }
  37.  
  38. /**
  39. Constructs the array with separate X, and Y sizes
  40. */
  41. Array2D(unsigned int initialSizeX, unsigned int initialSizeY) {
  42. this->sizeX = initialSizeX;
  43. this->sizeY = initialSizeY;
  44. this->data = new T[sizeX * sizeY];
  45. }
  46.  
  47. /**
  48. Copies an existing Array2D
  49. */
  50. Array2D(Array2D<T>* copy) {
  51. this->sizeX = copy->sizeX;
  52. this->sizeY = copy->sizeY;
  53. this->data = new T[sizeX * sizeY];
  54.  
  55. for (int y = 0; y < sizeY; y++) {
  56. for (int x = 0; x < sizeX; x++) {
  57. this->data[x*sizeX + y] = copy->data[x*sizeX + y];
  58. }
  59. }
  60. }
  61.  
  62. ~Array2D() {
  63. if (data != NULL)
  64. delete[] data;
  65. }
  66.  
  67. int getSize() {
  68. return sizeX;
  69. }
  70. int getSizeX() {
  71. return sizeX;
  72. }
  73. int getSizeY() {
  74. return sizeY;
  75. }
  76.  
  77. inline int getIndex(int x, int y) {
  78. return x*sizeX + y;
  79. }
  80. inline int getIndexClamped(int x, int y) {
  81. return max(0, min(x, sizeX - 1)) * size + max(0, min(y, sizeY - 1));
  82. }
  83. inline int getIndexWrapped(int x, int y) {
  84. return (x < 0 ? sizeX + x : (x >= sizeX ? y % (sizeX - 1) : x)) * sizeX + (y<0 > sizeY + y : (y >= sizeX ? y % (sizeY - 1) : x));
  85. }
  86.  
  87. /**
  88. Returns the value at the given index X, and Y.
  89. WARNING: Makes no protective measures for the validity of the indexes
  90. */
  91. T getValue(int x, int y) {
  92. return data[ getIndex(x,y) ];
  93. }
  94.  
  95. /**
  96. Returns the value at the given index X, and Y.
  97. If the indices are not in range, it will clamp them to their respective borders
  98. */
  99. T getValueClamped(int x, int y) {
  100. return data[ getIndexClamped(x,y) ];
  101. }
  102.  
  103. /**
  104. Returns the value at the given index X, and Y.
  105. If the indices are not in range, it will wrap the overflowing remainder around.
  106. This is intended for use in graphics/kernel arrays where a seamless action across
  107. the array is expected
  108. */
  109. T getValueWrapped(int x, int y) {
  110. return data[ getIndexWrapped(x,y) ];
  111. }
  112.  
  113. /**
  114. Sets the value at the given indices X, and Y.
  115. WARNING: Makes no protections that the indices are in bounds!
  116. */
  117. void setValue(T value, int x, int y) {
  118. this->data[getIndex(x, y)] = value;
  119. }
  120.  
  121. /**
  122. Sets the value at the given indices X, and Y.
  123. If the indices are not in range, it will clamp them to their respective borders
  124. */
  125. void setValueClamped(T value, int x, int y) {
  126. this->data[getIndexClamped(x, y)] = value;
  127. }
  128.  
  129. /**
  130. Sets the value at the given indices X, and Y.
  131. If the indices are not in range, it will wrap the overflowing remainder around.
  132. This is intended for use in graphics/kernel arrays where a seamless action across
  133. the array is expected
  134. */
  135. void setValueWrapped(T value, int x, int y) {
  136. this->data[getIndexWrapped(x, y)] = value;
  137. }
  138.  
  139. /**
  140. Copies an Array2D by assignment
  141. */
  142. T& operator=(const T& other) {
  143. if (this != &other) {
  144. if (other.sizeX != sizeX || other.sizeY != sizeY) {
  145. delete[] data;
  146. sizeX = other.sizeX;
  147. sizeY = other.sizeY;
  148.  
  149. data = nullptr;
  150. data = new T[sizeX * sizeY];
  151. }
  152. std::copy(other.data, other.data + (other.sizeX * other.sizeY), data);
  153. }
  154. return *this;
  155. }
  156.  
  157. /**
  158. Access an index directly as if Array2D itself was a 1D array.
  159. */
  160. T& operator[](std::size_t index) {
  161. return data[index];
  162. }
  163.  
  164. /**
  165. Return a value from the data.
  166. Same as getValue(x,y)
  167. */
  168. T operator()(int x, int y) {
  169. return getValue(x, y);
  170. }
  171.  
  172. /**
  173. Set a value
  174. Same as setValue(x,y)
  175. */
  176. void operator()(T value, int x, int y) {
  177. setValue(value, x, y);
  178. }
  179.  
  180. private:
  181. T* data;
  182. unsigned int sizeX, sizeY;
  183. };
Add Comment
Please, Sign In to add comment