string_sort_test.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // Boost Sort library string_sort_test.cpp file ----------------------------//
  2. // Copyright Steven Ross 2009. Use, modification and
  3. // distribution is subject to the Boost Software License, Version
  4. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. // See http://www.boost.org/libs/sort for library home page.
  7. #include <boost/sort/spreadsort/detail/string_sort.hpp>
  8. #include <boost/sort/spreadsort/string_sort.hpp>
  9. #include <boost/sort/spreadsort/spreadsort.hpp>
  10. // Include unit test framework
  11. #include <boost/test/included/test_exec_monitor.hpp>
  12. #include <boost/test/test_tools.hpp>
  13. #include <vector>
  14. #include <string>
  15. using namespace std;
  16. using namespace boost::sort::spreadsort;
  17. using boost::sort::spreadsort::detail::offset_less_than;
  18. using boost::sort::spreadsort::detail::offset_greater_than;
  19. using boost::sort::spreadsort::detail::update_offset;
  20. struct bracket {
  21. unsigned char operator()(const string &x, size_t offset) const {
  22. return x[offset];
  23. }
  24. };
  25. struct wbracket {
  26. wchar_t operator()(const wstring &x, size_t offset) const {
  27. return x[offset];
  28. }
  29. };
  30. struct get_size {
  31. size_t operator()(const string &x) const{ return x.size(); }
  32. };
  33. struct wget_size {
  34. size_t operator()(const wstring &x) const{ return x.size(); }
  35. };
  36. static const unsigned input_count = 100000;
  37. // Test that update_offset finds the first character with a difference.
  38. void update_offset_test() {
  39. vector<string> input;
  40. input.push_back("test1");
  41. input.push_back("test2");
  42. size_t char_offset = 1;
  43. update_offset<vector<string>::iterator, unsigned char>(input.begin(),
  44. input.end(),
  45. char_offset);
  46. BOOST_CHECK(char_offset == 4);
  47. // Functor version
  48. char_offset = 1;
  49. update_offset(input.begin(), input.end(), char_offset, bracket(), get_size());
  50. BOOST_CHECK(char_offset == 4);
  51. }
  52. // Test that offset comparison operators only look after the offset.
  53. void offset_comparison_test() {
  54. string input1 = "ab";
  55. string input2 = "ba";
  56. string input3 = "aba";
  57. offset_less_than<string, unsigned char> less_than(0);
  58. offset_greater_than<string, unsigned char> greater_than(0);
  59. BOOST_CHECK(less_than(input1, input2));
  60. BOOST_CHECK(less_than(input1, input3));
  61. BOOST_CHECK(!less_than(input2, input1));
  62. BOOST_CHECK(!less_than(input1, input1));
  63. BOOST_CHECK(!greater_than(input1, input2));
  64. BOOST_CHECK(!greater_than(input1, input3));
  65. BOOST_CHECK(greater_than(input2, input1));
  66. BOOST_CHECK(!greater_than(input1, input1));
  67. // Offset comparisons only check after the specified offset.
  68. offset_less_than<string, unsigned char> offset_less(1);
  69. offset_greater_than<string, unsigned char> offset_greater(1);
  70. BOOST_CHECK(!offset_less(input1, input2));
  71. BOOST_CHECK(offset_less(input1, input3));
  72. BOOST_CHECK(offset_less(input2, input1));
  73. BOOST_CHECK(!offset_less(input1, input1));
  74. BOOST_CHECK(offset_greater(input1, input2));
  75. BOOST_CHECK(!offset_greater(input1, input3));
  76. BOOST_CHECK(!offset_greater(input2, input1));
  77. BOOST_CHECK(!offset_greater(input1, input1));
  78. }
  79. void string_test()
  80. {
  81. // Prepare inputs
  82. vector<string> base_vec;
  83. const unsigned max_length = 32;
  84. srand(1);
  85. //Generating semirandom numbers
  86. for (unsigned u = 0; u < input_count; ++u) {
  87. unsigned length = rand() % max_length;
  88. string result;
  89. for (unsigned v = 0; v < length; ++v) {
  90. result.push_back(rand() % 256);
  91. }
  92. base_vec.push_back(result);
  93. }
  94. vector<string> sorted_vec = base_vec;
  95. vector<string> test_vec = base_vec;
  96. std::sort(sorted_vec.begin(), sorted_vec.end());
  97. //Testing basic call
  98. string_sort(test_vec.begin(), test_vec.end());
  99. BOOST_CHECK(test_vec == sorted_vec);
  100. //Testing boost::sort::spreadsort wrapper
  101. test_vec = base_vec;
  102. boost::sort::spreadsort::spreadsort(test_vec.begin(), test_vec.end());
  103. BOOST_CHECK(test_vec == sorted_vec);
  104. //Character functors
  105. test_vec = base_vec;
  106. string_sort(test_vec.begin(), test_vec.end(), bracket(), get_size());
  107. BOOST_CHECK(test_vec == sorted_vec);
  108. //All functors
  109. test_vec = base_vec;
  110. string_sort(test_vec.begin(), test_vec.end(), bracket(), get_size(),
  111. less<string>());
  112. BOOST_CHECK(test_vec == sorted_vec);
  113. //reverse order
  114. std::sort(sorted_vec.begin(), sorted_vec.end(), greater<string>());
  115. reverse_string_sort(test_vec.begin(), test_vec.end(), greater<string>());
  116. BOOST_CHECK(test_vec == sorted_vec);
  117. //reverse order with functors
  118. test_vec = base_vec;
  119. reverse_string_sort(test_vec.begin(), test_vec.end(), bracket(), get_size(),
  120. greater<string>());
  121. BOOST_CHECK(test_vec == sorted_vec);
  122. }
  123. // Verify that 0, 1, and input_count empty strings all sort correctly.
  124. void corner_test() {
  125. vector<string> test_vec;
  126. boost::sort::spreadsort::spreadsort(test_vec.begin(), test_vec.end());
  127. test_vec.resize(1);
  128. boost::sort::spreadsort::spreadsort(test_vec.begin(), test_vec.end());
  129. BOOST_CHECK(test_vec[0].empty());
  130. test_vec.resize(input_count);
  131. boost::sort::spreadsort::spreadsort(test_vec.begin(), test_vec.end());
  132. BOOST_CHECK(test_vec.size() == input_count);
  133. for (unsigned i = 0; i < test_vec.size(); ++i) {
  134. BOOST_CHECK(test_vec[i].empty());
  135. }
  136. }
  137. // test main
  138. int test_main( int, char*[] )
  139. {
  140. update_offset_test();
  141. offset_comparison_test();
  142. string_test();
  143. corner_test();
  144. return 0;
  145. }