sort_test.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * Copyright 2010-2025 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bx/blob/master/LICENSE
  4. */
  5. #include "test.h"
  6. #include <bx/bx.h>
  7. #include <bx/sort.h>
  8. #include <bx/string.h>
  9. #include <bx/rng.h>
  10. TEST_CASE("quickSort", "[sort]")
  11. {
  12. const char* str[] =
  13. {
  14. "jabuka",
  15. "kruska",
  16. "malina",
  17. "jagoda",
  18. };
  19. REQUIRE(!bx::isSorted(str, BX_COUNTOF(str) ) );
  20. bx::quickSort(str, BX_COUNTOF(str) );
  21. REQUIRE(0 == bx::strCmp(str[0], "jabuka") );
  22. REQUIRE(0 == bx::strCmp(str[1], "jagoda") );
  23. REQUIRE(0 == bx::strCmp(str[2], "kruska") );
  24. REQUIRE(0 == bx::strCmp(str[3], "malina") );
  25. REQUIRE(bx::isSorted(str, BX_COUNTOF(str) ) );
  26. int8_t byte[128];
  27. bx::RngMwc rng;
  28. for (uint32_t ii = 0; ii < BX_COUNTOF(byte); ++ii)
  29. {
  30. byte[ii] = rng.gen()&0xff;
  31. }
  32. REQUIRE(!bx::isSorted(byte, BX_COUNTOF(byte) ) );
  33. bx::quickSort(byte, BX_COUNTOF(byte) );
  34. for (uint32_t ii = 1; ii < BX_COUNTOF(byte); ++ii)
  35. {
  36. REQUIRE(byte[ii-1] <= byte[ii]);
  37. }
  38. REQUIRE(bx::isSorted(byte, BX_COUNTOF(byte) ) );
  39. }
  40. TEST_CASE("binarySearch", "[sort]")
  41. {
  42. const char* str[] =
  43. {
  44. "jabuka",
  45. "kruska",
  46. "malina",
  47. "jagoda",
  48. };
  49. REQUIRE(!bx::isSorted(str, BX_COUNTOF(str) ) );
  50. bx::quickSort(str, BX_COUNTOF(str) );
  51. REQUIRE(bx::isSorted(str, BX_COUNTOF(str) ) );
  52. auto bsearchStrCmpFn = [](const void* _lhs, const void* _rhs)
  53. {
  54. const char* lhs = (const char*)_lhs;
  55. const char* rhs = *(const char**)_rhs;
  56. return bx::strCmp(lhs, rhs);
  57. };
  58. REQUIRE(~4 == bx::binarySearch("sljiva", str, BX_COUNTOF(str), sizeof(str[0]), bsearchStrCmpFn) );
  59. REQUIRE( 0 == bx::binarySearch("jabuka", str, BX_COUNTOF(str), sizeof(str[0]), bsearchStrCmpFn) );
  60. REQUIRE( 1 == bx::binarySearch("jagoda", str, BX_COUNTOF(str), sizeof(str[0]), bsearchStrCmpFn) );
  61. REQUIRE( 2 == bx::binarySearch("kruska", str, BX_COUNTOF(str), sizeof(str[0]), bsearchStrCmpFn) );
  62. REQUIRE( 3 == bx::binarySearch("malina", str, BX_COUNTOF(str), sizeof(str[0]), bsearchStrCmpFn) );
  63. REQUIRE(~3 == bx::binarySearch("kupina", str, BX_COUNTOF(str), sizeof(str[0]), bsearchStrCmpFn) );
  64. REQUIRE( 0 == bx::lowerBound("jabuka", str, BX_COUNTOF(str), sizeof(str[0]), bsearchStrCmpFn) );
  65. REQUIRE( 1 == bx::upperBound("jabuka", str, BX_COUNTOF(str), sizeof(str[0]), bsearchStrCmpFn) );
  66. REQUIRE( 1 == bx::lowerBound("jagoda", str, BX_COUNTOF(str), sizeof(str[0]), bsearchStrCmpFn) );
  67. REQUIRE( 2 == bx::upperBound("jagoda", str, BX_COUNTOF(str), sizeof(str[0]), bsearchStrCmpFn) );
  68. REQUIRE( 2 == bx::lowerBound("kruska", str, BX_COUNTOF(str), sizeof(str[0]), bsearchStrCmpFn) );
  69. REQUIRE( 3 == bx::upperBound("kruska", str, BX_COUNTOF(str), sizeof(str[0]), bsearchStrCmpFn) );
  70. REQUIRE( 3 == bx::lowerBound("malina", str, BX_COUNTOF(str), sizeof(str[0]), bsearchStrCmpFn) );
  71. REQUIRE( 4 == bx::upperBound("malina", str, BX_COUNTOF(str), sizeof(str[0]), bsearchStrCmpFn) );
  72. }
  73. TEST_CASE("unique", "[sort]")
  74. {
  75. // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 | 14
  76. int32_t test[] = { 100, 101, 101, 101, 103, 104, 105, 105, 105, 106, 106, 107, 108, 109 };
  77. REQUIRE(bx::isSorted(test, BX_COUNTOF(test) ) );
  78. REQUIRE(0 == bx::unique(test, 0) );
  79. REQUIRE(1 == bx::unique(test, 1) );
  80. REQUIRE(2 == bx::unique(test, 4) );
  81. bx::quickSort(test, BX_COUNTOF(test) );
  82. REQUIRE(3 == bx::unique(test, 5) );
  83. bx::quickSort(test, BX_COUNTOF(test) );
  84. uint32_t last = bx::unique(test, BX_COUNTOF(test) );
  85. REQUIRE(9 == last);
  86. REQUIRE(9 == bx::unique(test, last) );
  87. }
  88. TEST_CASE("lowerBound, upperBound int32_t", "[sort]")
  89. {
  90. // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 | 14
  91. const int32_t test[] = { 100, 101, 101, 101, 103, 104, 105, 105, 105, 106, 106, 107, 108, 109 };
  92. REQUIRE(bx::isSorted(test, BX_COUNTOF(test) ) );
  93. const uint32_t resultLowerBound[] = { 0, 1, 4, 4, 5, 6, 9, 11, 12, 13 };
  94. const uint32_t resultUpperBound[] = { 1, 4, 4, 5, 6, 9, 11, 12, 13, 14 };
  95. STATIC_REQUIRE(10 == BX_COUNTOF(resultLowerBound) );
  96. STATIC_REQUIRE(10 == BX_COUNTOF(resultUpperBound) );
  97. for (int32_t key = test[0], keyMax = test[BX_COUNTOF(test)-1], ii = 0; key <= keyMax; ++key, ++ii)
  98. {
  99. REQUIRE(resultLowerBound[ii] == bx::lowerBound(key, test, BX_COUNTOF(test) ) );
  100. REQUIRE(resultUpperBound[ii] == bx::upperBound(key, test, BX_COUNTOF(test) ) );
  101. }
  102. }
  103. template<typename Ty>
  104. int32_t compareAscendingTest(const Ty& _lhs, const Ty& _rhs)
  105. {
  106. return bx::compareAscending<Ty>(&_lhs, &_rhs);
  107. }
  108. template<typename Ty>
  109. int32_t compareDescendingTest(const Ty& _lhs, const Ty& _rhs)
  110. {
  111. return bx::compareDescending<Ty>(&_lhs, &_rhs);
  112. }
  113. template<typename Ty>
  114. void compareTest(const Ty& _min, const Ty& _max)
  115. {
  116. REQUIRE(_min < _max);
  117. REQUIRE(-1 == compareAscendingTest<Ty>(bx::min<Ty>(), bx::max<Ty>() ) );
  118. REQUIRE(-1 == compareAscendingTest<Ty>(Ty(0), bx::max<Ty>() ) );
  119. REQUIRE( 0 == compareAscendingTest<Ty>(bx::min<Ty>(), bx::min<Ty>() ) );
  120. REQUIRE( 0 == compareAscendingTest<Ty>(bx::max<Ty>(), bx::max<Ty>() ) );
  121. REQUIRE( 1 == compareAscendingTest<Ty>(bx::max<Ty>(), Ty(0) ) );
  122. REQUIRE( 1 == compareAscendingTest<Ty>(bx::max<Ty>(), bx::min<Ty>() ) );
  123. REQUIRE(-1 == compareAscendingTest<Ty>(_min, _max) );
  124. REQUIRE( 0 == compareAscendingTest<Ty>(_min, _min) );
  125. REQUIRE( 0 == compareAscendingTest<Ty>(_max, _max) );
  126. REQUIRE( 1 == compareAscendingTest<Ty>(_max, _min) );
  127. REQUIRE( 1 == compareDescendingTest<Ty>(_min, _max) );
  128. REQUIRE( 0 == compareDescendingTest<Ty>(_min, _min) );
  129. REQUIRE( 0 == compareDescendingTest<Ty>(_max, _max) );
  130. REQUIRE(-1 == compareDescendingTest<Ty>(_max, _min) );
  131. }
  132. TEST_CASE("ComparisonFn", "[sort]")
  133. {
  134. compareTest< int8_t>( -13, 89);
  135. compareTest<int16_t>(-1389, 1389);
  136. compareTest<int32_t>(-1389, 1389);
  137. compareTest<int64_t>(-1389, 1389);
  138. compareTest< uint8_t>( 13, 89);
  139. compareTest<uint16_t>( 13, 1389);
  140. compareTest<uint32_t>( 13, 1389);
  141. compareTest<uint64_t>( 13, 1389);
  142. compareTest< float>(-13.89f, 1389.0f);
  143. compareTest<double>(-13.89f, 1389.0f);
  144. }