/Src/Dependencies/Boost/libs/iterator/doc/quickbook/permutation_iterator.qbk

http://hadesmem.googlecode.com/ · text · 207 lines · 147 code · 60 blank · 0 comment · 0 complexity · 9f531d4dc66a67a7a20ca394524083ac MD5 · raw file

  1. [section:permutation Permutation Iterator]
  2. The permutation iterator adaptor provides a permuted view of a given
  3. range. That is, the view includes every element of the given range but
  4. in a potentially different order. The adaptor takes two arguments:
  5. * an iterator to the range V on which the permutation
  6. will be applied
  7. * the reindexing scheme that defines how the
  8. elements of V will be permuted.
  9. Note that the permutation iterator is not limited to strict
  10. permutations of the given range V. The distance between begin and end
  11. of the reindexing iterators is allowed to be smaller compared to the
  12. size of the range V, in which case the permutation iterator only
  13. provides a permutation of a subrange of V. The indexes neither need
  14. to be unique. In this same context, it must be noted that the past the
  15. end permutation iterator is completely defined by means of the
  16. past-the-end iterator to the indices.
  17. [h2 Example]
  18. using namespace boost;
  19. int i = 0;
  20. typedef std::vector< int > element_range_type;
  21. typedef std::list< int > index_type;
  22. static const int element_range_size = 10;
  23. static const int index_size = 4;
  24. element_range_type elements( element_range_size );
  25. for(element_range_type::iterator el_it = elements.begin() ; el_it != elements.end() ; ++el_it)
  26. *el_it = std::distance(elements.begin(), el_it);
  27. index_type indices( index_size );
  28. for(index_type::iterator i_it = indices.begin() ; i_it != indices.end() ; ++i_it )
  29. *i_it = element_range_size - index_size + std::distance(indices.begin(), i_it);
  30. std::reverse( indices.begin(), indices.end() );
  31. typedef permutation_iterator< element_range_type::iterator, index_type::iterator > permutation_type;
  32. permutation_type begin = make_permutation_iterator( elements.begin(), indices.begin() );
  33. permutation_type it = begin;
  34. permutation_type end = make_permutation_iterator( elements.begin(), indices.end() );
  35. std::cout << "The original range is : ";
  36. std::copy( elements.begin(), elements.end(), std::ostream_iterator< int >( std::cout, " " ) );
  37. std::cout << "\n";
  38. std::cout << "The reindexing scheme is : ";
  39. std::copy( indices.begin(), indices.end(), std::ostream_iterator< int >( std::cout, " " ) );
  40. std::cout << "\n";
  41. std::cout << "The permutated range is : ";
  42. std::copy( begin, end, std::ostream_iterator< int >( std::cout, " " ) );
  43. std::cout << "\n";
  44. std::cout << "Elements at even indices in the permutation : ";
  45. it = begin;
  46. for(i = 0; i < index_size / 2 ; ++i, it+=2 ) std::cout << *it << " ";
  47. std::cout << "\n";
  48. std::cout << "Permutation backwards : ";
  49. it = begin + (index_size);
  50. assert( it != begin );
  51. for( ; it-- != begin ; ) std::cout << *it << " ";
  52. std::cout << "\n";
  53. std::cout << "Iterate backward with stride 2 : ";
  54. it = begin + (index_size - 1);
  55. for(i = 0 ; i < index_size / 2 ; ++i, it-=2 ) std::cout << *it << " ";
  56. std::cout << "\n";
  57. The output is:
  58. The original range is : 0 1 2 3 4 5 6 7 8 9
  59. The reindexing scheme is : 9 8 7 6
  60. The permutated range is : 9 8 7 6
  61. Elements at even indices in the permutation : 9 7
  62. Permutation backwards : 6 7 8 9
  63. Iterate backward with stride 2 : 6 8
  64. The source code for this example can be found
  65. [@../example/permutation_iter_example.cpp here].
  66. [h2 Reference]
  67. [h3 Synopsis]
  68. template< class ElementIterator
  69. , class IndexIterator
  70. , class ValueT = use_default
  71. , class CategoryT = use_default
  72. , class ReferenceT = use_default
  73. , class DifferenceT = use_default >
  74. class permutation_iterator
  75. {
  76. public:
  77. permutation_iterator();
  78. explicit permutation_iterator(ElementIterator x, IndexIterator y);
  79. template< class OEIter, class OIIter, class V, class C, class R, class D >
  80. permutation_iterator(
  81. permutation_iterator<OEIter, OIIter, V, C, R, D> const& r
  82. , typename enable_if_convertible<OEIter, ElementIterator>::type* = 0
  83. , typename enable_if_convertible<OIIter, IndexIterator>::type* = 0
  84. );
  85. reference operator*() const;
  86. permutation_iterator& operator++();
  87. ElementIterator const& base() const;
  88. private:
  89. ElementIterator m_elt; // exposition only
  90. IndexIterator m_order; // exposition only
  91. };
  92. template <class ElementIterator, class IndexIterator>
  93. permutation_iterator<ElementIterator, IndexIterator>
  94. make_permutation_iterator( ElementIterator e, IndexIterator i);
  95. [h3 Requirements]
  96. `ElementIterator` shall model Random Access Traversal Iterator.
  97. `IndexIterator` shall model Readable Iterator. The value type of
  98. the `IndexIterator` must be convertible to the difference type of
  99. `ElementIterator`.
  100. [h3 Concepts]
  101. `permutation_iterator` models the same iterator traversal concepts
  102. as `IndexIterator` and the same iterator access concepts as
  103. `ElementIterator`.
  104. If `IndexIterator` models Single Pass Iterator and
  105. `ElementIterator` models Readable Iterator then
  106. `permutation_iterator` models Input Iterator.
  107. If `IndexIterator` models Forward Traversal Iterator and
  108. `ElementIterator` models Readable Lvalue Iterator then
  109. `permutation_iterator` models Forward Iterator.
  110. If `IndexIterator` models Bidirectional Traversal Iterator and
  111. `ElementIterator` models Readable Lvalue Iterator then
  112. `permutation_iterator` models Bidirectional Iterator.
  113. If `IndexIterator` models Random Access Traversal Iterator and
  114. `ElementIterator` models Readable Lvalue Iterator then
  115. `permutation_iterator` models Random Access Iterator.
  116. `permutation_iterator<E1, X, V1, C2, R1, D1>` is interoperable
  117. with `permutation_iterator<E2, Y, V2, C2, R2, D2>` if and only if
  118. `X` is interoperable with `Y` and `E1` is convertible
  119. to `E2`.
  120. [h3 Operations]
  121. In addition to those operations required by the concepts that
  122. `permutation_iterator` models, `permutation_iterator` provides the
  123. following operations.
  124. permutation_iterator();
  125. [*Effects: ] Default constructs `m_elt` and `m_order`.
  126. explicit permutation_iterator(ElementIterator x, IndexIterator y);
  127. [*Effects: ] Constructs `m_elt` from `x` and `m_order` from `y`.
  128. template< class OEIter, class OIIter, class V, class C, class R, class D >
  129. permutation_iterator(
  130. permutation_iterator<OEIter, OIIter, V, C, R, D> const& r
  131. , typename enable_if_convertible<OEIter, ElementIterator>::type* = 0
  132. , typename enable_if_convertible<OIIter, IndexIterator>::type* = 0
  133. );
  134. [*Effects: ] Constructs `m_elt` from `r.m_elt` and
  135. `m_order` from `y.m_order`.
  136. reference operator*() const;
  137. [*Returns: ] `*(m_elt + *m_order)`
  138. permutation_iterator& operator++();
  139. [*Effects: ] `++m_order`\n
  140. [*Returns: ] `*this`
  141. ElementIterator const& base() const;
  142. [*Returns: ] `m_order`
  143. template <class ElementIterator, class IndexIterator>
  144. permutation_iterator<ElementIterator, IndexIterator>
  145. make_permutation_iterator(ElementIterator e, IndexIterator i);
  146. [*Returns: ] `permutation_iterator<ElementIterator, IndexIterator>(e, i)`
  147. [endsect]