Defined in header boost/permutation_iterator.hpp
The permutation iterator adaptor provides an iterator to a permutation of a given range. (see definition of permutation). The adaptor takes two arguments
Note that the permutation iterator is not limited to strict permutations of the given range V. The distance between begin and end of the reindexing iterators is allowed to be smaller compared to the size of the range V, in which case the permutation iterator only provides a permutation of a subrange of V. The indexes neither need to be unique. In this same context, it must be noted that the past the end permutation iterator is completely defined by means of the past-the-end iterator to the indices
namespace boost { template <class IndexIterator> class permutation_iterator_policies; template <class ElementIterator, class IndexIterator> class permutation_iterator_generator; template <class ElementIterator, class IndexIterator> typename permutation_iterator_generator<ElementIterator, IndexIterator>::type make_permutation_iterator(ElementIterator& base, IndexIterator& indexing); }
The permutation_iterator_generator
is a helper class whose purpose
is to construct a permutation iterator type. This class has
two template arguments, the first being the iterator type over the range V, the
second being the type of the iterator over the indices.
template <class ElementIterator, class IndexIterator> class permutation_iterator_generator { public: typedef iterator_adaptor<...> type; // the resulting permutation iterator type }
Parameter | Description |
---|---|
ElementIterator | The iterator over the elements to be permuted. This type must be a model of RandomAccessIterator |
IndexIterator | The iterator over the new indexing scheme. This type must at least be a model
of ForwardIterator.
The IndexIterator::value_type must be convertible to the
ElementIterator::difference_type . |
operator+=(distance)
, this operation will take linear time
in case the IndexIterator is a model of ForwardIterator instead of amortized constant time.
make_permutation_iterator()
function provides a
convenient way to create permutation iterator objects. The function
saves the user the trouble of explicitly writing out the iterator
types.
template <class ElementIterator, class IndexIterator > typename permutation_iterator_generator<ElementIterator, IndexIterator>::type make_permutation_iterator(ElementIterator& base, IndexIterator& indices);
using namespace boost; int i = 0; typedef std::vector< int > element_range_type; typedef std::list< int > index_type; static const int element_range_size = 10; static const int index_size = 4; element_range_type elements( element_range_size ); for(element_range_type::iterator el_it = elements.begin() ; el_it != elements.end() ; ++el_it) *el_it = std::distance(elements.begin(), el_it); index_type indices( index_size ); for(index_type::iterator i_it = indices.begin() ; i_it != indices.end() ; ++i_it ) *i_it = element_range_size - index_size + std::distance(indices.begin(), i_it); std::reverse( indices.begin(), indices.end() ); typedef permutation_iterator_generator< element_range_type::iterator, index_type::iterator >::type permutation_type; permutation_type begin = make_permutation_iterator( elements.begin(), indices.begin() ); permutation_type it = begin; permutation_type end = make_permutation_iterator( elements.begin(), indices.end() ); std::cout << "The original range is : "; std::copy( elements.begin(), elements.end(), std::ostream_iterator< int >( std::cout, " " ) ); std::cout << "\n"; std::cout << "The reindexing scheme is : "; std::copy( indices.begin(), indices.end(), std::ostream_iterator< int >( std::cout, " " ) ); std::cout << "\n"; std::cout << "The permutated range is : "; std::copy( begin, end, std::ostream_iterator< int >( std::cout, " " ) ); std::cout << "\n"; std::cout << "Elements at even indices in the permutation : "; it = begin; for(i = 0; i < index_size / 2 ; ++i, it+=2 ) std::cout << *it << " "; std::cout << "\n"; std::cout << "Permutation backwards : "; it = begin + (index_size); assert( it != begin ); for( ; it-- != begin ; ) std::cout << *it << " "; std::cout << "\n"; std::cout << "Iterate backward with stride 2 : "; it = begin + (index_size - 1); for(i = 0 ; i < index_size / 2 ; ++i, it-=2 ) std::cout << *it << " "; std::cout << "\n";