algorithmAPI.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. // zlib open source license
  2. //
  3. // Copyright (c) 2023 David Forsgren Piuva
  4. //
  5. // This software is provided 'as-is', without any express or implied
  6. // warranty. In no event will the authors be held liable for any damages
  7. // arising from the use of this software.
  8. //
  9. // Permission is granted to anyone to use this software for any purpose,
  10. // including commercial applications, and to alter it and redistribute it
  11. // freely, subject to the following restrictions:
  12. //
  13. // 1. The origin of this software must not be misrepresented; you must not
  14. // claim that you wrote the original software. If you use this software
  15. // in a product, an acknowledgment in the product documentation would be
  16. // appreciated but is not required.
  17. //
  18. // 2. Altered source versions must be plainly marked as such, and must not be
  19. // misrepresented as being the original software.
  20. //
  21. // 3. This notice may not be removed or altered from any source
  22. // distribution.
  23. #ifndef DFPSR_API_ALGORITHM
  24. #define DFPSR_API_ALGORITHM
  25. // TODO: Split Algorithm into smaller APIs for specific types and only have the methods that need more than one collection type in the exposed API.
  26. // This allow using the algorithm API for a specific type without bloating the dependencies with all the types and their functions.
  27. #include "../collection/List.h"
  28. #include "../collection/Array.h"
  29. #include "../collection/Field.h"
  30. #include "../collection/FixedArray.h"
  31. namespace dsr {
  32. // Returns true iff a and b are equal in length and content according to T's equality operator.
  33. template<typename T>
  34. bool operator==(const List<T>& a, const List<T>& b) {
  35. if (a.length() != b.length()) return false;
  36. for (intptr_t i = 0; i < a.length(); i++) {
  37. if (!(a[i] == b[i])) return false;
  38. }
  39. return true;
  40. }
  41. // Returns true iff a and b are equal in length and content according to T's equality operator.
  42. template<typename T>
  43. bool operator==(const Array<T>& a, const Array<T>& b) {
  44. if (a.length() != b.length()) return false;
  45. for (intptr_t i = 0; i < a.length(); i++) {
  46. if (!(a[i] == b[i])) return false;
  47. }
  48. return true;
  49. }
  50. // Returns true iff a and b are equal in content according to T's equality operator.
  51. // If the lengths do not match, the call will not be compiled.
  52. template<typename T, intptr_t LENGTH>
  53. bool operator==(const FixedArray<T, LENGTH>& a, const FixedArray<T, LENGTH>& b) {
  54. for (intptr_t i = 0; i < LENGTH; i++) {
  55. if (!(a[i] == b[i])) return false;
  56. }
  57. return true;
  58. }
  59. // Returns true iff a and b have the same dimensions and content according to T's equality operator.
  60. template<typename T>
  61. bool operator==(const Field<T>& a, const Field<T>& b) {
  62. if (a.width() != b.width()
  63. || a.height() != b.height()) return false;
  64. for (intptr_t y = 0; y < a.height(); y++) {
  65. for (intptr_t x = 0; x < a.width(); x++) {
  66. if (!(a.unsafe_readAccess(x, y) == b.unsafe_readAccess(x, y))) return false;
  67. }
  68. }
  69. return true;
  70. }
  71. // Returns false iff a and b are equal in length and content according to T's equality operator.
  72. template<typename T> bool operator!=(const List<T>& a, const List<T>& b) { return !(a == b); }
  73. // Returns false iff a and b are equal in length and content according to T's equality operator.
  74. template<typename T> bool operator!=(const Array<T>& a, const Array<T>& b) { return !(a == b); }
  75. // Returns false iff a and b are equal in content according to T's equality operator.
  76. template<typename T, intptr_t LENGTH> bool operator!=(const FixedArray<T, LENGTH>& a, const FixedArray<T, LENGTH>& b) { return !(a == b); }
  77. // Returns false iff a and b have the same dimensions and content according to T's equality operator.
  78. template<typename T> bool operator!=(const Field<T>& a, const Field<T>& b) { return !(a == b); }
  79. // Internal helper function
  80. template<typename T>
  81. String& print_collection_1D_multiline(String& target, const T& collection, const ReadableString& indentation) {
  82. string_append(target, indentation, U"{\n");
  83. intptr_t maxIndex = collection.length() - 1;
  84. for (intptr_t i = 0; i <= maxIndex; i++) {
  85. string_toStreamIndented(target, collection[i], indentation + "\t");
  86. if (i < maxIndex) {
  87. string_append(target, U",");
  88. }
  89. string_append(target, U"\n");
  90. }
  91. string_append(target, indentation, U"}");
  92. return target;
  93. }
  94. // Printing a generic List of elements for easy debugging.
  95. // A new line is used after each element, because the element type might print using multiple lines and the list might be very long.
  96. // No new line at the end, because the caller might want to add a comma before breaking the line.
  97. // If string_toStreamIndented is defined for lists of a specific element type, this template function will be overridden by the more specific function.
  98. template<typename T>
  99. String& string_toStreamIndented(String& target, const List<T>& collection, const ReadableString& indentation) {
  100. return print_collection_1D_multiline(target, collection, indentation);
  101. }
  102. // Printing a generic Array of elements for easy debugging, using the same syntax as when printing List.
  103. template<typename T>
  104. String& string_toStreamIndented(String& target, const Array<T>& collection, const ReadableString& indentation) {
  105. return print_collection_1D_multiline(target, collection, indentation);
  106. }
  107. // Printing a generic FixedArray of elements for easy debugging, using the same syntax as when printing List.
  108. template<typename T, intptr_t LENGTH>
  109. String& string_toStreamIndented(String& target, const FixedArray<T, LENGTH>& collection, const ReadableString& indentation) {
  110. return print_collection_1D_multiline(target, collection, indentation);
  111. }
  112. // Printing a generic Field of elements for easy debugging.
  113. template<typename T>
  114. String& string_toStreamIndented(String& target, const Field<T>& collection, const ReadableString& indentation) {
  115. string_append(target, indentation, U"{\n");
  116. intptr_t maxX = collection.width() - 1;
  117. intptr_t maxY = collection.height() - 1;
  118. for (intptr_t y = 0; y <= maxY; y++) {
  119. string_append(target, indentation, U"\t{\n");
  120. for (intptr_t x = 0; x <= maxX; x++) {
  121. string_toStreamIndented(target, collection.unsafe_readAccess(IVector2D(x, y)), indentation + "\t\t");
  122. if (x < maxX) {
  123. string_append(target, U",");
  124. }
  125. string_append(target, U"\n");
  126. }
  127. string_append(target, indentation, U"\t}");
  128. if (y < maxY) {
  129. string_append(target, U",");
  130. }
  131. string_append(target, U"\n");
  132. }
  133. string_append(target, indentation, U"}");
  134. return target;
  135. }
  136. // TODO: Implement functional sort, concatenation, union, search and conversion algorithms for List, Array, Field and FixedArray.
  137. // in a separate "algorithm" API that does not have to be exposed in headers when using the collection types.
  138. }
  139. #endif