permutation_iterator_test.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // (C) Copyright Toon Knapen 2001.
  2. // (C) Copyright Roland Richter 2003.
  3. // Distributed under the Boost Software License, Version 1.0. (See
  4. // accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #include <boost/config.hpp>
  7. #include <boost/test/minimal.hpp>
  8. #include <boost/iterator/permutation_iterator.hpp>
  9. #include <boost/static_assert.hpp>
  10. #include <boost/iterator/iterator_concepts.hpp>
  11. #include <boost/concept/assert.hpp>
  12. #include <vector>
  13. #include <list>
  14. #include <algorithm>
  15. // This test checks for convertibility/interoperability among similar
  16. // permutation iterators. We're not using container iterators
  17. // underneath, as in permutation_test, because of bugs in GCC-3.3's
  18. // __normal_iterator that make is_convertible choke when testing
  19. // convertibility.
  20. void iterop_test()
  21. {
  22. typedef boost::permutation_iterator< double*, int const* > permutation_type;
  23. typedef boost::permutation_iterator< double const*, int const* > permutation_const_type;
  24. BOOST_CONCEPT_ASSERT((
  25. boost_concepts::InteroperableIteratorConcept<
  26. permutation_type
  27. , permutation_const_type
  28. >));
  29. }
  30. void permutation_test()
  31. {
  32. // Example taken from documentation of old permutation_iterator.
  33. typedef std::vector< double > element_range_type;
  34. typedef std::list< int > index_type;
  35. const int element_range_size = 10;
  36. const int index_size = 7;
  37. BOOST_STATIC_ASSERT(index_size <= element_range_size);
  38. element_range_type elements( element_range_size );
  39. for( element_range_type::iterator el_it = elements.begin(); el_it != elements.end(); ++el_it )
  40. { *el_it = std::distance(elements.begin(), el_it); }
  41. index_type indices( index_size );
  42. for( index_type::iterator i_it = indices.begin(); i_it != indices.end(); ++i_it )
  43. { *i_it = element_range_size - index_size + std::distance(indices.begin(), i_it); }
  44. std::reverse( indices.begin(), indices.end() );
  45. typedef boost::permutation_iterator< element_range_type::iterator, index_type::iterator > permutation_type;
  46. permutation_type begin = boost::make_permutation_iterator( elements.begin(), indices.begin() );
  47. permutation_type it = begin;
  48. permutation_type end = boost::make_permutation_iterator( elements.begin(), indices.end() );
  49. BOOST_CHECK( it == begin );
  50. BOOST_CHECK( it != end );
  51. BOOST_CHECK( std::distance( begin, end ) == index_size );
  52. for( index_type::iterator i_it1 = indices.begin(); it != end; ++i_it1, ++it )
  53. {
  54. BOOST_CHECK( *it == elements[ *i_it1 ] );
  55. }
  56. it = begin;
  57. for( int i1 = 0; i1 < index_size - 1 ; ++++i1, ++++it )
  58. {
  59. index_type::iterator i_it2 = indices.begin();
  60. std::advance( i_it2, i1 );
  61. BOOST_CHECK( *it == elements[ *i_it2 ] );
  62. }
  63. it = begin;
  64. std::advance(it, index_size);
  65. for( index_type::iterator i_it3 = indices.end(); it != begin; )
  66. {
  67. BOOST_CHECK( *--it == elements[ *--i_it3 ] );
  68. }
  69. it = begin;
  70. std::advance(it, index_size);
  71. for( int i2 = 0; i2 < index_size - 1; i2+=2, --it )
  72. {
  73. index_type::iterator i_it4 = --indices.end();
  74. std::advance( i_it4, -i2 );
  75. BOOST_CHECK( *--it == elements[ *i_it4 ] );
  76. }
  77. }
  78. int test_main(int, char *[])
  79. {
  80. permutation_test();
  81. return 0;
  82. }