algorithmAPI.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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. namespace dsr {
  31. // Returns true iff a and b are equal in length and content according to T's equality operator.
  32. template<typename T>
  33. bool operator==(const List<T>& a, const List<T>& b) {
  34. if (a.length() != b.length()) return false;
  35. for (int64_t i = 0; i < a.length(); i++) {
  36. if (!(a[i] == b[i])) return false;
  37. }
  38. return true;
  39. }
  40. // Returns true iff a and b are equal in length and content according to T's equality operator.
  41. template<typename T>
  42. bool operator==(const Array<T>& a, const Array<T>& b) {
  43. if (a.length() != b.length()) return false;
  44. for (int64_t i = 0; i < a.length(); i++) {
  45. if (!(a[i] == b[i])) return false;
  46. }
  47. return true;
  48. }
  49. // Returns true iff a and b have the same dimensions and content according to T's equality operator.
  50. template<typename T>
  51. bool operator==(const Field<T>& a, const Field<T>& b) {
  52. if (a.width() != b.width()
  53. || a.height() != b.height()) return false;
  54. for (int64_t y = 0; y < a.height(); y++) {
  55. for (int64_t x = 0; x < a.width(); x++) {
  56. if (!(a.unsafe_readAccess(IVector2D(x, y)) == b.unsafe_readAccess(IVector2D(x, y)))) return false;
  57. }
  58. }
  59. return true;
  60. }
  61. // Returns false iff a and b are equal in length and content according to T's equality operator.
  62. template<typename T> bool operator!=(const List<T>& a, const List<T>& b) { return !(a == b); }
  63. // Returns false iff a and b are equal in length and content according to T's equality operator.
  64. template<typename T> bool operator!=(const Array<T>& a, const Array<T>& b) { return !(a == b); }
  65. // Returns false iff a and b have the same dimensions and content according to T's equality operator.
  66. template<typename T> bool operator!=(const Field<T>& a, const Field<T>& b) { return !(a == b); }
  67. // Internal helper function
  68. template<typename T>
  69. String& print_collection_1D_multiline(String& target, const T& collection, const ReadableString& indentation) {
  70. string_append(target, indentation, U"{\n");
  71. int64_t maxIndex = collection.length() - 1;
  72. for (int64_t i = 0; i <= maxIndex; i++) {
  73. string_toStreamIndented(target, collection[i], indentation + "\t");
  74. if (i < maxIndex) {
  75. string_append(target, U",");
  76. }
  77. string_append(target, U"\n");
  78. }
  79. string_append(target, indentation, U"}");
  80. return target;
  81. }
  82. // Printing a generic List of elements for easy debugging.
  83. // A new line is used after each element, because the element type might print using multiple lines and the list might be very long.
  84. // No new line at the end, because the caller might want to add a comma before breaking the line.
  85. // If string_toStreamIndented is defined for lists of a specific element type, this template function will be overridden by the more specific function.
  86. template<typename T>
  87. String& string_toStreamIndented(String& target, const List<T>& collection, const ReadableString& indentation) {
  88. return print_collection_1D_multiline(target, collection, indentation);
  89. }
  90. // Printing a generic Array of elements for easy debugging, using the same syntax as when printing List.
  91. template<typename T>
  92. String& string_toStreamIndented(String& target, const Array<T>& collection, const ReadableString& indentation) {
  93. return print_collection_1D_multiline(target, collection, indentation);
  94. }
  95. // Printing a generic Field of elements for easy debugging.
  96. template<typename T>
  97. String& string_toStreamIndented(String& target, const Field<T>& collection, const ReadableString& indentation) {
  98. string_append(target, indentation, U"{\n");
  99. int64_t maxX = collection.width() - 1;
  100. int64_t maxY = collection.height() - 1;
  101. for (int64_t y = 0; y <= maxY; y++) {
  102. string_append(target, indentation, U"\t{");
  103. for (int64_t x = 0; x <= maxX; x++) {
  104. string_toStreamIndented(target, collection.unsafe_readAccess(IVector2D(x, y)), indentation + "\t\t");
  105. if (x < maxX) {
  106. string_append(target, U",");
  107. }
  108. string_append(target, U"\n");
  109. }
  110. if (y < maxY) {
  111. // Comma separate rows on a separate line, to avoid having too much indentation.
  112. string_append(target, U"\n", indentation, U"\t,");
  113. }
  114. string_append(target, U"\n", indentation, U"\t{\n");
  115. }
  116. string_append(target, indentation, U"}");
  117. return target;
  118. }
  119. // TODO: Implement functional sort, concatenation, union, search and conversion algorithms for List, Array and Field.
  120. // in a separate "algorithm" API that does not have to be exposed in headers when using the collection types.
  121. }
  122. #endif