adaptor.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. #include <list>
  12. #include <vector>
  13. #include <sstream>
  14. #include <range/v3/core.hpp>
  15. #include <range/v3/utility/copy.hpp>
  16. #include <range/v3/view/delimit.hpp>
  17. #include "../simple_test.hpp"
  18. #include "../test_utils.hpp"
  19. template<typename BidiRange>
  20. struct my_reverse_view
  21. : ranges::view_adaptor<my_reverse_view<BidiRange>, BidiRange>
  22. {
  23. private:
  24. CPP_assert(ranges::bidirectional_range<BidiRange>);
  25. CPP_assert(ranges::common_range<BidiRange>);
  26. friend ranges::range_access;
  27. using base_iterator_t = ranges::iterator_t<BidiRange>;
  28. struct adaptor : ranges::adaptor_base
  29. {
  30. template<class base_mixin>
  31. struct mixin : base_mixin
  32. {
  33. mixin() = default;
  34. using base_mixin::base_mixin;
  35. int mixin_int = 120;
  36. int base_plus_adaptor() const
  37. {
  38. int y = this->get().t;
  39. return *this->base() + y;
  40. }
  41. };
  42. int t = 20;
  43. // Cross-wire begin and end.
  44. base_iterator_t begin(my_reverse_view const &rng) const
  45. {
  46. return ranges::end(rng.base());
  47. }
  48. base_iterator_t end(my_reverse_view const &rng) const
  49. {
  50. return ranges::begin(rng.base());
  51. }
  52. void next(base_iterator_t &it) const
  53. {
  54. --it;
  55. }
  56. void prev(base_iterator_t &it) const
  57. {
  58. ++it;
  59. }
  60. ranges::range_reference_t<BidiRange> read(base_iterator_t it) const
  61. {
  62. return *ranges::prev(it);
  63. }
  64. CPP_member
  65. auto advance(base_iterator_t &it,
  66. ranges::range_difference_t<BidiRange> n) const ->
  67. CPP_ret(void)(
  68. requires ranges::random_access_range<BidiRange>)
  69. {
  70. it -= n;
  71. }
  72. CPP_member
  73. auto distance_to(base_iterator_t const &here,
  74. base_iterator_t const &there) const ->
  75. CPP_ret(ranges::range_difference_t<BidiRange>)(
  76. requires ranges::sized_sentinel_for<base_iterator_t, base_iterator_t>)
  77. {
  78. return here - there;
  79. }
  80. };
  81. adaptor begin_adaptor() const
  82. {
  83. return {};
  84. }
  85. adaptor end_adaptor() const
  86. {
  87. return {};
  88. }
  89. public:
  90. using my_reverse_view::view_adaptor::view_adaptor;
  91. };
  92. struct my_delimited_range
  93. : ranges::view_adaptor<
  94. my_delimited_range,
  95. ranges::delimit_view<ranges::istream_view<int>, int>>
  96. {
  97. using view_adaptor::view_adaptor;
  98. struct adaptor : ranges::adaptor_base
  99. {
  100. template<class base_mixin>
  101. struct mixin : base_mixin
  102. {
  103. mixin() = default;
  104. using base_mixin::base_mixin;
  105. int mixin_int = 120;
  106. int adaptor_access_test() const
  107. {
  108. int y = this->get().t;
  109. return y;
  110. }
  111. };
  112. int t = 20;
  113. };
  114. adaptor begin_adaptor() const
  115. {
  116. return {};
  117. }
  118. adaptor end_adaptor() const
  119. {
  120. return {};
  121. }
  122. };
  123. int main()
  124. {
  125. using namespace ranges;
  126. std::vector<int> v{1, 2, 3, 4};
  127. my_reverse_view<std::vector<int>&> retro{v};
  128. CPP_assert(common_range<decltype(retro)>);
  129. CPP_assert(view_<decltype(retro)>);
  130. CPP_assert(random_access_iterator<decltype(retro.begin())>);
  131. ::check_equal(retro, {4, 3, 2, 1});
  132. // test cursor mixin
  133. CHECK( retro.begin().mixin_int == 120 );
  134. CHECK( *((retro.begin()+1).base()) == 4 );
  135. CHECK( (retro.begin()+1).base_plus_adaptor() == 24 );
  136. std::list<int> l{1, 2, 3, 4};
  137. my_reverse_view<std::list<int>& > retro2{l};
  138. CPP_assert(common_range<decltype(retro2)>);
  139. CPP_assert(view_<decltype(retro2)>);
  140. CPP_assert(bidirectional_iterator<decltype(retro2.begin())>);
  141. CPP_assert(!random_access_iterator<decltype(retro2.begin())>);
  142. ::check_equal(retro2, {4, 3, 2, 1});
  143. std::stringstream sinx("1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 42 6 7 8 9 ");
  144. my_delimited_range r{views::delimit(istream<int>(sinx), 42)};
  145. CPP_assert(view_<decltype(r)>);
  146. CPP_assert(!common_range<decltype(r)>);
  147. CPP_assert(input_iterator<decltype(r.begin())>);
  148. CPP_assert(!forward_iterator<decltype(r.begin())>);
  149. ::check_equal(r, {1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4});
  150. // test sentinel mixin
  151. CHECK(r.end().mixin_int == 120);
  152. CHECK(r.end().adaptor_access_test() == 20);
  153. return ::test_result();
  154. }