indexed.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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. //
  9. // For more information, see http://www.boost.org/libs/range/
  10. //
  11. #include <boost/range/adaptor/indexed.hpp>
  12. #include <boost/test/test_tools.hpp>
  13. #include <boost/test/unit_test.hpp>
  14. #include <boost/assign.hpp>
  15. #include <boost/foreach.hpp>
  16. #include <boost/range/algorithm_ext.hpp>
  17. #include <boost/range/concepts.hpp>
  18. #include <algorithm>
  19. #include <list>
  20. #include <vector>
  21. #include "../test_utils.hpp"
  22. namespace boost_range_test
  23. {
  24. namespace
  25. {
  26. template<typename Container, typename AdaptedRange>
  27. void check_result(
  28. const Container& reference_range,
  29. const AdaptedRange& adapted_range,
  30. std::ptrdiff_t start_index
  31. )
  32. {
  33. typedef typename boost::range_iterator<const Container>::type
  34. reference_iterator;
  35. typedef typename boost::range_iterator<const AdaptedRange>::type
  36. adapted_iterator;
  37. BOOST_REQUIRE_EQUAL(boost::size(reference_range),
  38. boost::size(adapted_range));
  39. reference_iterator reference_it = boost::begin(reference_range);
  40. adapted_iterator adapted_it = boost::begin(adapted_range);
  41. for (std::ptrdiff_t i = start_index;
  42. reference_it != boost::end(reference_range);
  43. ++reference_it, ++adapted_it, ++i)
  44. {
  45. BOOST_CHECK_EQUAL(i, adapted_it->index());
  46. BOOST_CHECK_EQUAL(*reference_it, adapted_it->value());
  47. }
  48. }
  49. template<typename Container>
  50. void indexed_test_impl(Container& c, std::ptrdiff_t start_index)
  51. {
  52. // This is my preferred syntax using the | operator.
  53. check_result(c, c | boost::adaptors::indexed(), 0);
  54. check_result(c, c | boost::adaptors::indexed(start_index), start_index);
  55. // This is the function syntax
  56. check_result(c, boost::adaptors::index(c), 0);
  57. check_result(c, boost::adaptors::index(c, start_index), start_index);
  58. }
  59. template<typename Container>
  60. void indexed_test_impl(Container& c)
  61. {
  62. indexed_test_impl(c, 0);
  63. indexed_test_impl(c, -1);
  64. indexed_test_impl(c, 4);
  65. }
  66. template<typename Container>
  67. void indexed_test_impl()
  68. {
  69. using namespace boost::assign;
  70. Container c;
  71. // test empty container
  72. indexed_test_impl(c);
  73. // test one element
  74. c += 1;
  75. indexed_test_impl(c);
  76. // test many elements
  77. c += 1,2,2,2,3,4,4,4,4,5,6,7,8,9,9;
  78. indexed_test_impl(c);
  79. }
  80. template<typename Traversal, typename Range>
  81. void check_traversal(const Range& rng)
  82. {
  83. BOOST_STATIC_ASSERT(
  84. boost::is_convertible<
  85. typename boost::range_traversal<const Range>::type,
  86. Traversal
  87. >::value);
  88. }
  89. template<typename Traversal, typename Range>
  90. void check_not_traversal(const Range& rng)
  91. {
  92. BOOST_STATIC_ASSERT(
  93. !boost::is_convertible<
  94. typename boost::range_traversal<const Range>::type,
  95. Traversal
  96. >::value);
  97. }
  98. void indexed_test()
  99. {
  100. indexed_test_impl< std::vector< int > >();
  101. indexed_test_impl< std::list< int > >();
  102. std::vector<int> vi;
  103. check_traversal<boost::random_access_traversal_tag>(
  104. vi | boost::adaptors::indexed());
  105. std::list<int> li;
  106. check_traversal<boost::forward_traversal_tag>(
  107. li | boost::adaptors::indexed());
  108. check_not_traversal<boost::bidirectional_traversal_tag>(
  109. li | boost::adaptors::indexed());
  110. check_not_traversal<boost::random_access_traversal_tag>(
  111. li | boost::adaptors::indexed());
  112. }
  113. } // anonymous namesapce
  114. } // namespace boost_range_test
  115. boost::unit_test::test_suite*
  116. init_unit_test_suite(int, char*[])
  117. {
  118. boost::unit_test::test_suite* test
  119. = BOOST_TEST_SUITE( "Boost.Range indexed adaptor test suite" );
  120. test->add(BOOST_TEST_CASE(&boost_range_test::indexed_test));
  121. return test;
  122. }