iota.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. // Range v3 library
  2. //
  3. // Copyright Eric Niebler 2014-present
  4. //
  5. // Use, modification and distribution is subject to the
  6. // Boost Software License, Version 1.0. (See accompanying
  7. // file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // Project home: https://github.com/ericniebler/range-v3
  11. //
  12. #include <range/v3/core.hpp>
  13. #include <range/v3/utility/copy.hpp>
  14. #include <range/v3/view/c_str.hpp>
  15. #include <range/v3/view/indices.hpp>
  16. #include <range/v3/view/indirect.hpp>
  17. #include <range/v3/view/iota.hpp>
  18. #include <range/v3/view/take.hpp>
  19. #include <range/v3/view/drop_exactly.hpp>
  20. #include "../simple_test.hpp"
  21. #include "../test_utils.hpp"
  22. #include "../test_iterators.hpp"
  23. struct Int
  24. {
  25. using difference_type = int;
  26. int i = 0;
  27. Int() = default;
  28. explicit Int(int j) : i(j) {}
  29. Int & operator++() {++i; CHECK(i <= 10); return *this;}
  30. Int operator++(int) {auto tmp = *this; ++*this; return tmp;}
  31. bool operator==(Int j) const { return i == j.i; }
  32. bool operator!=(Int j) const { return i != j.i; }
  33. };
  34. CPP_template(typename I)(
  35. requires ranges::integral<I>)
  36. void test_iota_distance()
  37. {
  38. using namespace ranges;
  39. using D = iter_difference_t<I>;
  40. I max = std::numeric_limits<I>::max();
  41. CHECK(detail::iota_distance_(I(0), I(0)) == D(0));
  42. CHECK(detail::iota_distance_(I(1), I(0)) == D(-1));
  43. CHECK(detail::iota_distance_(I(0), I(1)) == D(1));
  44. CHECK(detail::iota_distance_(I(1), I(1)) == D(0));
  45. CHECK(detail::iota_distance_(I(max - I(1)), I(max - I(1))) == D(0));
  46. CHECK(detail::iota_distance_(I(max), I(max - I(1))) == D(-1));
  47. CHECK(detail::iota_distance_(I(max - I(1)), I(max)) == D(1));
  48. CHECK(detail::iota_distance_(I(max), I(max)) == D(0));
  49. }
  50. int main()
  51. {
  52. using namespace ranges;
  53. {
  54. CPP_assert(random_access_range<decltype(views::iota((unsigned short)0))>);
  55. CPP_assert(random_access_range<decltype(views::iota(0))>);
  56. static_assert(is_infinite<decltype(views::iota(0))>::value, "");
  57. static_assert(is_infinite<decltype(views::drop_exactly(views::iota(0),0))>::value, "");
  58. static_assert(!sized_range<decltype(views::iota(0))>, "");
  59. }
  60. {
  61. char const *sz = "hello world";
  62. ::check_equal(views::iota(ForwardIterator<char const*>(sz)) | views::take(10) | views::indirect,
  63. {'h','e','l','l','o',' ','w','o','r','l'});
  64. ::check_equal(views::ints | views::take(10), {0,1,2,3,4,5,6,7,8,9});
  65. ::check_equal(views::ints(0,unreachable) | views::take(10), {0,1,2,3,4,5,6,7,8,9});
  66. ::check_equal(views::ints(0,9), {0,1,2,3,4,5,6,7,8});
  67. ::check_equal(views::closed_indices(0,9), {0,1,2,3,4,5,6,7,8,9});
  68. ::check_equal(views::ints(1,10), {1,2,3,4,5,6,7,8,9});
  69. ::check_equal(views::closed_indices(1,10), {1,2,3,4,5,6,7,8,9,10});
  70. }
  71. {
  72. auto chars = views::ints(std::numeric_limits<signed char>::min(),
  73. std::numeric_limits<signed char>::max());
  74. CPP_assert(random_access_range<decltype(chars)>);
  75. CPP_assert(same_as<int, range_difference_t<decltype(chars)>>);
  76. CPP_assert(view_<decltype(chars)>);
  77. CPP_assert(random_access_range<decltype(chars)>);
  78. CPP_assert(common_range<decltype(chars)>);
  79. CHECK(distance(chars.begin(), chars.end()) == (long) CHAR_MAX - (long) CHAR_MIN);
  80. CHECK(chars.size() == (unsigned)((long) CHAR_MAX - (long) CHAR_MIN));
  81. }
  82. {
  83. auto ushorts = views::ints(std::numeric_limits<unsigned short>::min(),
  84. std::numeric_limits<unsigned short>::max());
  85. CPP_assert(view_<decltype(ushorts)>);
  86. CPP_assert(common_range<decltype(ushorts)>);
  87. CPP_assert(same_as<int, range_difference_t<decltype(ushorts)>>);
  88. CPP_assert(same_as<unsigned int, range_size_t<decltype(ushorts)>>);
  89. CHECK(distance(ushorts.begin(), ushorts.end()) == (int) USHRT_MAX);
  90. CHECK(ushorts.size() == (unsigned) USHRT_MAX);
  91. }
  92. {
  93. auto uints = views::closed_indices(
  94. std::numeric_limits<std::uint_least32_t>::min(),
  95. std::numeric_limits<std::uint_least32_t>::max() - 1);
  96. CPP_assert(view_<decltype(uints)>);
  97. CPP_assert(common_range<decltype(uints)>);
  98. CPP_assert(same_as<std::int_fast64_t, range_difference_t<decltype(uints)>>);
  99. CPP_assert(same_as<std::uint_fast64_t, range_size_t<decltype(uints)>>);
  100. CHECK(uints.size() == std::numeric_limits<std::uint32_t>::max());
  101. }
  102. {
  103. auto is = views::closed_indices(
  104. std::numeric_limits<std::int_least32_t>::min(),
  105. std::numeric_limits<std::int_least32_t>::max() - 1);
  106. CPP_assert(same_as<std::int_fast64_t, range_difference_t<decltype(is)>>);
  107. CPP_assert(same_as<std::uint_fast64_t, range_size_t<decltype(is)>>);
  108. CHECK(is.size() == std::numeric_limits<std::uint32_t>::max());
  109. }
  110. {
  111. auto sints = views::ints(std::numeric_limits<int>::min(),
  112. std::numeric_limits<int>::max());
  113. CPP_assert(random_access_range<decltype(sints)>);
  114. CPP_assert(same_as<std::int_fast64_t, range_difference_t<decltype(sints)>>);
  115. CPP_assert(view_<decltype(sints)>);
  116. CPP_assert(random_access_range<decltype(sints)>);
  117. CPP_assert(common_range<decltype(sints)>);
  118. CHECK(distance(sints.begin(), sints.end()) == (std::int_fast64_t) INT_MAX - (std::int_fast64_t) INT_MIN);
  119. CHECK(sints.size() == (std::uint_fast64_t)((std::int_fast64_t) INT_MAX - (std::int_fast64_t) INT_MIN));
  120. }
  121. {
  122. auto is = views::closed_iota(Int{0}, Int{10});
  123. ::check_equal(is, {Int{0},Int{1},Int{2},Int{3},Int{4},Int{5},Int{6},Int{7},Int{8},Int{9},Int{10}});
  124. CPP_assert(view_<decltype(is)>);
  125. CPP_assert(common_range<decltype(is)>);
  126. CPP_assert(!sized_range<decltype(is)>);
  127. CPP_assert(forward_range<decltype(is)>);
  128. CPP_assert(!bidirectional_range<decltype(is)>);
  129. }
  130. {
  131. auto is = views::closed_iota(0, 10);
  132. ::check_equal(is, {0,1,2,3,4,5,6,7,8,9,10});
  133. CPP_assert(view_<decltype(is)>);
  134. CPP_assert(common_range<decltype(is)>);
  135. CPP_assert(sized_range<decltype(is)>);
  136. CPP_assert(random_access_range<decltype(is)>);
  137. CHECK(size(is) == 11u);
  138. auto it = is.begin(), e = is.end(), be = e;
  139. --be;
  140. using D = range_difference_t<decltype(is)>;
  141. // CHECK op++ and op-
  142. for(D i = 0; ; ++i)
  143. {
  144. CHECK((e - it) == (11 - i));
  145. CHECK((it - e) == -(11 - i));
  146. CHECK((be - it) == (10 - i));
  147. CHECK((it - be) == -(10 - i));
  148. if(i == 11) break;
  149. ++it;
  150. }
  151. // CHECK op-- and op-
  152. for(D i = 11; ; --i)
  153. {
  154. CHECK((e - it) == (11 - i));
  155. CHECK((it - e) == -(11 - i));
  156. CHECK((be - it) == (10 - i));
  157. CHECK((it - be) == -(10 - i));
  158. if(i == 0) break;
  159. --it;
  160. }
  161. // CHECK op+= and op-
  162. for(D i = 0; ; ++i)
  163. {
  164. it = next(is.begin(), i);
  165. CHECK((e - it) == (11 - i));
  166. CHECK((it - e) == -(11 - i));
  167. CHECK((be - it) == (10 - i));
  168. CHECK((it - be) == -(10 - i));
  169. if(i == 11) break;
  170. }
  171. // CHECK op-
  172. CHECK((e - 0) == e);
  173. CHECK((be - 0) == be);
  174. CHECK((e - 1) == be);
  175. CHECK((be - 1) == is.begin() + 9);
  176. }
  177. { // iota distance tests
  178. test_iota_distance<int8_t>();
  179. test_iota_distance<int16_t>();
  180. test_iota_distance<int32_t>();
  181. test_iota_distance<int64_t>();
  182. test_iota_distance<uint8_t>();
  183. test_iota_distance<uint16_t>();
  184. test_iota_distance<uint32_t>();
  185. test_iota_distance<uint64_t>();
  186. }
  187. {
  188. // https://github.com/ericniebler/range-v3/issues/506
  189. auto cstr = views::c_str((const char*)"hello world");
  190. auto cstr2 = views::iota(cstr.begin(), cstr.end()) | views::indirect;
  191. ::check_equal(cstr2, std::string("hello world"));
  192. auto i = cstr2.begin();
  193. i += 4;
  194. CHECK(*i == 'o');
  195. CHECK((i - cstr2.begin()) == 4);
  196. }
  197. { // test views::indices/closed_indices
  198. ::check_equal(views::indices | views::take(10), std::initializer_list<std::size_t>{0,1,2,3,4,5,6,7,8,9});
  199. ::check_equal(views::indices(0, 10), {0,1,2,3,4,5,6,7,8,9});
  200. ::check_equal(views::closed_indices(0, 10), {0,1,2,3,4,5,6,7,8,9,10});
  201. ::check_equal(views::indices(10), {0,1,2,3,4,5,6,7,8,9});
  202. ::check_equal(views::closed_indices(10), {0,1,2,3,4,5,6,7,8,9,10});
  203. }
  204. return ::test_result();
  205. }