
[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/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`\n
[*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]