iterator_range_drop.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // Boost.Range library
  2. //
  3. // Copyright Neil Groves 2014. 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. // For more information, see http://www.boost.org/libs/range/
  9. //
  10. #include <boost/detail/workaround.hpp>
  11. #include <boost/range/iterator_range_core.hpp>
  12. #include <boost/cstdint.hpp>
  13. #include <boost/test/test_tools.hpp>
  14. #include <boost/test/unit_test.hpp>
  15. #include <vector>
  16. namespace boost_range_test
  17. {
  18. namespace
  19. {
  20. class single_pass_iterator
  21. : public boost::iterator_facade<
  22. single_pass_iterator,
  23. boost::int32_t,
  24. boost::single_pass_traversal_tag,
  25. const boost::int32_t&
  26. >
  27. {
  28. friend class boost::iterator_core_access;
  29. typedef std::vector<boost::int32_t>::const_iterator iterator_t;
  30. public:
  31. single_pass_iterator() { }
  32. explicit single_pass_iterator(iterator_t it)
  33. : m_it(it)
  34. {
  35. }
  36. private:
  37. void increment()
  38. {
  39. ++m_it;
  40. }
  41. bool equal(single_pass_iterator other) const
  42. {
  43. return m_it == other.m_it;
  44. }
  45. reference dereference() const
  46. {
  47. return *m_it;
  48. }
  49. iterator_t m_it;
  50. };
  51. class bidirectional_iterator
  52. : public boost::iterator_facade<
  53. bidirectional_iterator,
  54. boost::int32_t,
  55. boost::bidirectional_traversal_tag,
  56. const boost::int32_t&
  57. >
  58. {
  59. friend class boost::iterator_core_access;
  60. typedef std::vector<boost::int32_t>::const_iterator iterator_t;
  61. public:
  62. bidirectional_iterator() { }
  63. explicit bidirectional_iterator(iterator_t it)
  64. : m_it(it)
  65. {
  66. }
  67. private:
  68. void increment()
  69. {
  70. ++m_it;
  71. }
  72. void decrement()
  73. {
  74. --m_it;
  75. }
  76. bool equal(bidirectional_iterator other) const
  77. {
  78. return m_it == other.m_it;
  79. }
  80. reference dereference() const
  81. {
  82. return *m_it;
  83. }
  84. iterator_t m_it;
  85. };
  86. template<typename SinglePassRange>
  87. boost::iterator_range<single_pass_iterator>
  88. single_pass_range(const SinglePassRange& rng)
  89. {
  90. return boost::iterator_range<single_pass_iterator>(
  91. single_pass_iterator(boost::begin(rng)),
  92. single_pass_iterator(boost::end(rng)));
  93. }
  94. template<typename BidirectionalRange>
  95. boost::iterator_range<bidirectional_iterator>
  96. bidirectional_range(const BidirectionalRange& rng)
  97. {
  98. return boost::iterator_range<bidirectional_iterator>(
  99. bidirectional_iterator(boost::begin(rng)),
  100. bidirectional_iterator(boost::end(rng)));
  101. }
  102. void test_drop_front()
  103. {
  104. std::vector<boost::int32_t> v;
  105. std::vector<boost::int32_t> ref_output;
  106. for (boost::int32_t i = 0; i < 10; ++i)
  107. {
  108. v.push_back(i);
  109. ref_output.push_back(i);
  110. }
  111. boost::iterator_range<single_pass_iterator> rng = single_pass_range(v);
  112. BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(),
  113. ref_output.begin(), ref_output.end());
  114. rng.drop_front();
  115. ref_output.erase(ref_output.begin());
  116. BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(),
  117. ref_output.begin(), ref_output.end());
  118. rng.drop_front(5);
  119. ref_output.erase(ref_output.begin(), ref_output.begin() + 5);
  120. BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(),
  121. ref_output.begin(), ref_output.end());
  122. }
  123. void test_drop_back()
  124. {
  125. std::vector<boost::int32_t> v;
  126. std::vector<boost::int32_t> ref_output;
  127. for (boost::int32_t i = 0; i < 10; ++i)
  128. {
  129. v.push_back(i);
  130. ref_output.push_back(i);
  131. }
  132. boost::iterator_range<bidirectional_iterator> rng = bidirectional_range(v);
  133. BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(),
  134. ref_output.begin(), ref_output.end());
  135. rng.drop_back();
  136. ref_output.pop_back();
  137. BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(),
  138. ref_output.begin(), ref_output.end());
  139. rng.drop_back(5);
  140. ref_output.erase(ref_output.end() - 5, ref_output.end());
  141. BOOST_CHECK_EQUAL_COLLECTIONS(rng.begin(), rng.end(),
  142. ref_output.begin(), ref_output.end());
  143. }
  144. } // anonymous namespace
  145. } // namespace boost_range_test
  146. boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
  147. {
  148. boost::unit_test::test_suite* test =
  149. BOOST_TEST_SUITE("Boost.Range iterator_range drop functions");
  150. test->add(BOOST_TEST_CASE(&boost_range_test::test_drop_front));
  151. test->add(BOOST_TEST_CASE(&boost_range_test::test_drop_back));
  152. return test;
  153. }