irange.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // Boost.Range library
  2. //
  3. // Copyright Neil Groves 2010. Use, modification and
  4. // distribution is subject to the Boost Software License, Version
  5. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. //
  9. // For more information, see http://www.boost.org/libs/range/
  10. //
  11. #include <boost/range/irange.hpp>
  12. #include <boost/range/algorithm_ext.hpp>
  13. #include <boost/range/begin.hpp>
  14. #include <boost/range/end.hpp>
  15. #include <boost/test/test_tools.hpp>
  16. #include <boost/test/unit_test.hpp>
  17. #include <vector>
  18. namespace boost
  19. {
  20. // Test an integer range with a step size of 1.
  21. template<typename Integer>
  22. void test_irange_impl(Integer last)
  23. {
  24. std::vector<Integer> reference;
  25. for (Integer i = static_cast<Integer>(0); i < last; ++i)
  26. {
  27. reference.push_back(i);
  28. }
  29. std::vector<Integer> test;
  30. boost::push_back(test, boost::irange(last));
  31. BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(),
  32. reference.begin(), reference.end() );
  33. }
  34. // Test an integer range with a step size of 1.
  35. template<typename Integer>
  36. void test_irange_impl(Integer first, Integer last)
  37. {
  38. std::vector<Integer> reference;
  39. for (Integer i = first; i < last; ++i)
  40. {
  41. reference.push_back(i);
  42. }
  43. std::vector<Integer> test;
  44. boost::push_back(test, boost::irange(first, last));
  45. BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(),
  46. reference.begin(), reference.end() );
  47. }
  48. // Test an integer range with a runtime specified step size.
  49. template<typename Integer, typename IntegerInput>
  50. void test_irange_impl(IntegerInput first, IntegerInput last, int step)
  51. {
  52. BOOST_ASSERT( step != 0 );
  53. // Skip tests that have negative values if the type is
  54. // unsigned
  55. if ((static_cast<IntegerInput>(static_cast<Integer>(first)) != first)
  56. || (static_cast<IntegerInput>(static_cast<Integer>(last)) != last))
  57. return;
  58. std::vector<Integer> reference;
  59. const std::ptrdiff_t first_p = static_cast<std::ptrdiff_t>(first);
  60. const std::ptrdiff_t last_p = static_cast<std::ptrdiff_t>(last);
  61. const std::ptrdiff_t step_p = static_cast<std::ptrdiff_t>(step);
  62. for (std::ptrdiff_t current_value = first_p;
  63. step_p >= 0 ? current_value < last_p : current_value > last_p;
  64. current_value += step_p)
  65. reference.push_back(current_value);
  66. std::vector<Integer> test;
  67. boost::push_back(test, boost::irange(first, last, step));
  68. BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(),
  69. reference.begin(), reference.end() );
  70. }
  71. // Test driver function that for an integer range [first, last)
  72. // drives the test implementation through various integer
  73. // types.
  74. void test_irange(int last)
  75. {
  76. test_irange_impl<signed char>(last);
  77. test_irange_impl<unsigned char>(last);
  78. test_irange_impl<signed short>(last);
  79. test_irange_impl<unsigned short>(last);
  80. test_irange_impl<signed int>(last);
  81. test_irange_impl<unsigned int>(last);
  82. test_irange_impl<signed long>(last);
  83. test_irange_impl<unsigned long>(last);
  84. }
  85. // Test driver function that for an integer range [first, last)
  86. // drives the test implementation through various integer
  87. // types.
  88. void test_irange(int first, int last)
  89. {
  90. test_irange_impl<signed char>(first,last);
  91. test_irange_impl<unsigned char>(first, last);
  92. test_irange_impl<signed short>(first, last);
  93. test_irange_impl<unsigned short>(first, last);
  94. test_irange_impl<signed int>(first, last);
  95. test_irange_impl<unsigned int>(first, last);
  96. test_irange_impl<signed long>(first, last);
  97. test_irange_impl<unsigned long>(first, last);
  98. }
  99. // Test driver function that for an integer range [first, last)
  100. // drives the test implementation through various integer
  101. // types step_size items at a time.
  102. void test_irange(int first, int last, int step_size)
  103. {
  104. BOOST_ASSERT( step_size != 0 );
  105. test_irange_impl<signed char>(first, last, step_size);
  106. test_irange_impl<unsigned char>(first, last, step_size);
  107. test_irange_impl<signed short>(first, last, step_size);
  108. test_irange_impl<unsigned short>(first, last, step_size);
  109. test_irange_impl<signed int>(first, last, step_size);
  110. test_irange_impl<unsigned int>(first, last, step_size);
  111. test_irange_impl<signed long>(first, last, step_size);
  112. test_irange_impl<unsigned long>(first, last, step_size);
  113. }
  114. // Implementation of the unit test for the integer range
  115. // function.
  116. // This starts the test drivers to drive a set of integer types
  117. // for a combination of range values chosen to exercise a large
  118. // number of implementation branches.
  119. void irange_unit_test()
  120. {
  121. // Test the single-step version of irange(last)
  122. test_irange(0);
  123. test_irange(1);
  124. test_irange(10);
  125. // Test the single-step version of irange(first, last)
  126. test_irange(0, 0);
  127. test_irange(0, 1);
  128. test_irange(0, 10);
  129. test_irange(1, 1);
  130. test_irange(1, 2);
  131. test_irange(1, 11);
  132. // Test the n-step version of irange(first, last, step-size)
  133. test_irange(0, 0, 1);
  134. test_irange(0, 0, -1);
  135. test_irange(0, 10, 1);
  136. test_irange(10, 0, -1);
  137. test_irange(0, 2, 2);
  138. test_irange(2, 0, -2);
  139. test_irange(0, 9, 2);
  140. test_irange(9, 0, -2);
  141. test_irange(-9, 0, 2);
  142. test_irange(-9, 9, 2);
  143. test_irange(9, -9, -2);
  144. test_irange(10, 20, 5);
  145. test_irange(20, 10, -5);
  146. test_irange(0, 0, 3);
  147. test_irange(0, 1, 3);
  148. test_irange(0, 2, 3);
  149. test_irange(0, 3, 3);
  150. test_irange(0, 4, 3);
  151. test_irange(0, 10, 3);
  152. test_irange(0, 0, -3);
  153. test_irange(0, -1, -3);
  154. test_irange(0, -2, -3);
  155. test_irange(0, -3, -3);
  156. test_irange(0, -4, -3);
  157. test_irange(0, -10, -3);
  158. }
  159. } // namespace boost
  160. boost::unit_test::test_suite*
  161. init_unit_test_suite(int argc, char* argv[])
  162. {
  163. boost::unit_test::test_suite* test
  164. = BOOST_TEST_SUITE( "RangeTestSuite.irange" );
  165. test->add(BOOST_TEST_CASE( &boost::irange_unit_test ));
  166. return test;
  167. }