mirror of
				https://github.com/boostorg/iterator.git
				synced 2025-11-03 18:01:37 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			208 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			208 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
 | 
						|
[section:permutation Permutation Iterator]
 | 
						|
 | 
						|
The permutation iterator adaptor provides a permuted view of a given
 | 
						|
range. That is, the view includes every element of the given range but
 | 
						|
in a potentially different order. The adaptor takes two arguments:
 | 
						|
 | 
						|
* an iterator to the range V on which the permutation
 | 
						|
  will be applied
 | 
						|
* the reindexing scheme that defines how the
 | 
						|
  elements of V will be permuted.
 | 
						|
 | 
						|
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.
 | 
						|
 | 
						|
[h2 Example]
 | 
						|
 | 
						|
    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< element_range_type::iterator, index_type::iterator > 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";
 | 
						|
 | 
						|
 | 
						|
The output is:
 | 
						|
 | 
						|
    The original range is : 0 1 2 3 4 5 6 7 8 9 
 | 
						|
    The reindexing scheme is : 9 8 7 6 
 | 
						|
    The permutated range is : 9 8 7 6 
 | 
						|
    Elements at even indices in the permutation : 9 7 
 | 
						|
    Permutation backwards : 6 7 8 9 
 | 
						|
    Iterate backward with stride 2 : 6 8 
 | 
						|
 | 
						|
 | 
						|
The source code for this example can be found
 | 
						|
[example_link permutation_iter_example.cpp..here].
 | 
						|
 | 
						|
[h2 Reference]
 | 
						|
 | 
						|
[h3 Synopsis]
 | 
						|
 | 
						|
  template< class ElementIterator
 | 
						|
    , class IndexIterator
 | 
						|
    , class ValueT        = use_default
 | 
						|
    , class CategoryT     = use_default
 | 
						|
    , class ReferenceT    = use_default
 | 
						|
    , class DifferenceT   = use_default >
 | 
						|
  class permutation_iterator
 | 
						|
  {
 | 
						|
  public:
 | 
						|
    permutation_iterator();
 | 
						|
    explicit permutation_iterator(ElementIterator x, IndexIterator y);
 | 
						|
 | 
						|
    template< class OEIter, class OIIter, class V, class C, class R, class D >
 | 
						|
    permutation_iterator(
 | 
						|
      permutation_iterator<OEIter, OIIter, V, C, R, D> const& r
 | 
						|
      , typename enable_if_convertible<OEIter, ElementIterator>::type* = 0
 | 
						|
      , typename enable_if_convertible<OIIter, IndexIterator>::type* = 0
 | 
						|
    );
 | 
						|
    reference operator*() const;
 | 
						|
    permutation_iterator& operator++();
 | 
						|
    ElementIterator const& base() const;
 | 
						|
  private:
 | 
						|
    ElementIterator m_elt;      // exposition only
 | 
						|
    IndexIterator m_order;      // exposition only
 | 
						|
  };
 | 
						|
 | 
						|
  template <class ElementIterator, class IndexIterator>
 | 
						|
  permutation_iterator<ElementIterator, IndexIterator> 
 | 
						|
  make_permutation_iterator( ElementIterator e, IndexIterator i);
 | 
						|
 | 
						|
 | 
						|
[h3 Requirements]
 | 
						|
 | 
						|
`ElementIterator` shall model Random Access Traversal Iterator.
 | 
						|
`IndexIterator` shall model Readable Iterator.  The value type of
 | 
						|
the `IndexIterator` must be convertible to the difference type of
 | 
						|
`ElementIterator`.
 | 
						|
 | 
						|
[h3 Concepts]
 | 
						|
 | 
						|
`permutation_iterator` models the same iterator traversal concepts
 | 
						|
as `IndexIterator` and the same iterator access concepts as
 | 
						|
`ElementIterator`.
 | 
						|
 | 
						|
If `IndexIterator` models Single Pass Iterator and 
 | 
						|
`ElementIterator` models Readable Iterator then
 | 
						|
`permutation_iterator` models Input Iterator.
 | 
						|
 | 
						|
If `IndexIterator` models Forward Traversal Iterator and 
 | 
						|
`ElementIterator` models Readable Lvalue Iterator then
 | 
						|
`permutation_iterator` models Forward Iterator.
 | 
						|
 | 
						|
If `IndexIterator` models Bidirectional Traversal Iterator and 
 | 
						|
`ElementIterator` models Readable Lvalue Iterator then
 | 
						|
`permutation_iterator` models Bidirectional Iterator.
 | 
						|
 | 
						|
If `IndexIterator` models Random Access Traversal Iterator and
 | 
						|
`ElementIterator` models Readable Lvalue Iterator then
 | 
						|
`permutation_iterator` models Random Access Iterator.
 | 
						|
 | 
						|
`permutation_iterator<E1, X, V1, C2, R1, D1>` is interoperable
 | 
						|
with `permutation_iterator<E2, Y, V2, C2, R2, D2>` if and only if
 | 
						|
`X` is interoperable with `Y` and `E1` is convertible
 | 
						|
to `E2`.
 | 
						|
 | 
						|
[h3 Operations]
 | 
						|
 | 
						|
In addition to those operations required by the concepts that
 | 
						|
`permutation_iterator` models, `permutation_iterator` provides the
 | 
						|
following operations.
 | 
						|
 | 
						|
  permutation_iterator();
 | 
						|
 | 
						|
[*Effects: ] Default constructs `m_elt` and `m_order`.
 | 
						|
 | 
						|
 | 
						|
  explicit permutation_iterator(ElementIterator x, IndexIterator y);
 | 
						|
 | 
						|
[*Effects: ] Constructs `m_elt` from `x` and `m_order` from `y`.
 | 
						|
 | 
						|
 | 
						|
    template< class OEIter, class OIIter, class V, class C, class R, class D >
 | 
						|
    permutation_iterator(
 | 
						|
      permutation_iterator<OEIter, OIIter, V, C, R, D> const& r
 | 
						|
      , typename enable_if_convertible<OEIter, ElementIterator>::type* = 0
 | 
						|
      , typename enable_if_convertible<OIIter, IndexIterator>::type* = 0
 | 
						|
    );
 | 
						|
 | 
						|
[*Effects: ] Constructs `m_elt` from `r.m_elt` and
 | 
						|
  `m_order` from `y.m_order`.
 | 
						|
 | 
						|
 | 
						|
  reference operator*() const;
 | 
						|
 | 
						|
[*Returns: ] `*(m_elt + *m_order)`
 | 
						|
 | 
						|
 | 
						|
  permutation_iterator& operator++();
 | 
						|
 | 
						|
[*Effects: ] `++m_order`[br]
 | 
						|
[*Returns: ] `*this`
 | 
						|
 | 
						|
 | 
						|
  ElementIterator const& base() const;
 | 
						|
 | 
						|
[*Returns: ] `m_order`
 | 
						|
 | 
						|
 | 
						|
  template <class ElementIterator, class IndexIterator>
 | 
						|
  permutation_iterator<ElementIterator, IndexIterator> 
 | 
						|
  make_permutation_iterator(ElementIterator e, IndexIterator i);
 | 
						|
 | 
						|
[*Returns: ] `permutation_iterator<ElementIterator, IndexIterator>(e, i)`
 | 
						|
 | 
						|
[endsect]
 |