operations.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. // Range v3 library
  2. //
  3. // Copyright Eric Niebler 2014-present
  4. // Copyright Michel Morin 2014
  5. //
  6. // Use, modification and distribution is subject to the
  7. // Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // Project home: https://github.com/ericniebler/range-v3
  12. #include <forward_list>
  13. #include <list>
  14. #include <vector>
  15. #include <limits>
  16. #include <range/v3/core.hpp>
  17. #include <range/v3/view/iota.hpp>
  18. #include <range/v3/view/take_while.hpp>
  19. #include "../array.hpp"
  20. #include "../simple_test.hpp"
  21. #include "../test_utils.hpp"
  22. template<typename I, typename S>
  23. void test_iterators(I first, S last, ranges::iter_difference_t<I> n)
  24. {
  25. using namespace ranges;
  26. CHECK(distance(first, last) == n);
  27. CHECK(distance_compare(first, last, n) == 0);
  28. CHECK(distance_compare(first, last, n - 1) > 0);
  29. CHECK(distance_compare(first, last, n + 1) < 0);
  30. CHECK(distance_compare(first, last, (std::numeric_limits<iter_difference_t<I>>::min)()) > 0);
  31. CHECK(distance_compare(first, last, (std::numeric_limits<iter_difference_t<I>>::max)()) < 0);
  32. }
  33. template<typename Rng>
  34. void test_range(Rng&& rng, ranges::range_difference_t<Rng> n)
  35. {
  36. using namespace ranges;
  37. CHECK(distance(rng) == n);
  38. CHECK(distance_compare(rng, n) == 0);
  39. CHECK(distance_compare(rng, n - 1) > 0);
  40. CHECK(distance_compare(rng, n + 1) < 0);
  41. CHECK(distance_compare(rng, (std::numeric_limits<range_difference_t<Rng>>::min)()) > 0);
  42. CHECK(distance_compare(rng, (std::numeric_limits<range_difference_t<Rng>>::max)()) < 0);
  43. }
  44. template<typename Rng>
  45. void test_infinite_range(Rng&& rng)
  46. {
  47. using namespace ranges;
  48. CHECK(distance_compare(rng, 0) > 0);
  49. CHECK(distance_compare(rng,-1) > 0);
  50. CHECK(distance_compare(rng, 1) > 0);
  51. CHECK(distance_compare(rng, (std::numeric_limits<range_difference_t<Rng>>::min)()) > 0);
  52. if (is_infinite<Rng>::value) {
  53. // For infinite ranges that can be detected by is_infinite<Rng> traits,
  54. // distance_compare can compute the result in constant time.
  55. CHECK(distance_compare(rng, (std::numeric_limits<range_difference_t<Rng>>::max)()) > 0);
  56. }
  57. else {
  58. // For other infinite ranges, comparing to a huge number might take too much time.
  59. // Thus commented out the test.
  60. // CHECK(distance_compare(rng, (std::numeric_limits<range_difference_t<Rng>>::max)()) > 0);
  61. }
  62. }
  63. constexpr bool test_constexpr()
  64. {
  65. using namespace ranges;
  66. auto rng = test::array<int, 10>{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}};
  67. using Rng = decltype(rng);
  68. auto bit = ranges::begin(rng);
  69. using I = decltype(bit);
  70. auto it = bit + 5;
  71. auto eit = ranges::end(rng);
  72. auto n = ranges::distance(rng);
  73. auto en = ranges::enumerate(rng);
  74. STATIC_CHECK_RETURN(n == 10);
  75. STATIC_CHECK_RETURN(distance(bit, eit) == n);
  76. STATIC_CHECK_RETURN(distance(it, eit) == 5);
  77. STATIC_CHECK_RETURN(distance_compare(bit, eit, n) == 0);
  78. STATIC_CHECK_RETURN(distance_compare(bit, eit, n - 1) > 0);
  79. STATIC_CHECK_RETURN(distance_compare(bit, eit, n + 1) < 0);
  80. STATIC_CHECK_RETURN(distance_compare(bit, eit, (std::numeric_limits<iter_difference_t<I>>::min)()) > 0);
  81. STATIC_CHECK_RETURN(distance_compare(bit, eit, (std::numeric_limits<iter_difference_t<I>>::max)()) < 0);
  82. STATIC_CHECK_RETURN(distance(rng) == n);
  83. STATIC_CHECK_RETURN(distance_compare(rng, n) == 0);
  84. STATIC_CHECK_RETURN(distance_compare(rng, n - 1) > 0);
  85. STATIC_CHECK_RETURN(distance_compare(rng, n + 1) < 0);
  86. STATIC_CHECK_RETURN(distance_compare(rng, (std::numeric_limits<range_difference_t<Rng>>::min)()) > 0);
  87. STATIC_CHECK_RETURN(distance_compare(rng, (std::numeric_limits<range_difference_t<Rng>>::max)()) < 0);
  88. STATIC_CHECK_RETURN(en.first == 10);
  89. STATIC_CHECK_RETURN(en.second == eit);
  90. return true;
  91. }
  92. int main()
  93. {
  94. using namespace ranges;
  95. {
  96. using cont_t = std::vector<int>;
  97. cont_t c {1, 2, 3, 4};
  98. test_range(c, 4);
  99. test_iterators(c.begin(), c.end(), 4);
  100. c.clear();
  101. test_range(c, 0);
  102. test_iterators(c.begin(), c.end(), 0);
  103. }
  104. {
  105. using cont_t = std::list<int>;
  106. cont_t c {1, 2, 3, 4};
  107. test_range(c, 4);
  108. test_iterators(c.begin(), c.end(), 4);
  109. c.clear();
  110. test_range(c, 0);
  111. test_iterators(c.begin(), c.end(), 0);
  112. }
  113. {
  114. using cont_t = std::forward_list<int>;
  115. cont_t c {1, 2, 3, 4};
  116. test_range(c, 4);
  117. test_iterators(c.begin(), c.end(), 4);
  118. c.clear();
  119. test_range(c, 0);
  120. test_iterators(c.begin(), c.end(), 0);
  121. }
  122. {
  123. int a[] = {1, 2, 3, 4};
  124. test_iterators(a + 4, a, -4);
  125. }
  126. {
  127. test_range(views::iota(0) | views::take_while([](int i) { return i < 4; }), 4);
  128. }
  129. {
  130. test_infinite_range(views::iota(0u));
  131. }
  132. {
  133. STATIC_CHECK(test_constexpr());
  134. }
  135. return ::test_result();
  136. }