# Combinations and Permutations

## Contents

- Introduction
- Examples
- Performance Considerations
- Synopsis
- Specification
- Implementation

## Introduction

It doesn't happen very often, but every once in awhile one needs to iterate over all of the combinations or permutations of a set of objects. Or more specifically, given a set of `N` objects, you want to consider `r` of them at a time (for each combination or permutation). The standard library offers `next_permutation`, but this offering alone has a few drawbacks:

- `next_permutation` only offers permutations of `N` objects taken `N` at a time. If you only need to consider permutations of length `r` chosen from a list of length `N` then you can save a factor of `(n-r)!` by iterating over only the permutations you need. If `r` is small compared to `N` this can easily be several orders of magnitude faster than iterating over all `N!` permutations.
- If one only needs permutations, but not the reverse permutation, a factor of 2 can be saved by iterating only over reversible permutations.
- If your permutations are of a circular nature, you can save a factor of `r` by iterating over only distinct circular permutations.
- If your permutations are of a circular nature and it doesn't matter whether your permutation goes in a clockwise or counter-clockwise direction, then iterating only over distinct reversible, circular permutations can save a factor of `2r` iterations compared to iterating over all `N!` permutations.
- If you're examining permutations of length `r` out of a list of length `N` and order doesn't matter at all in each list of length `r`, then it is far cheaper to iterate only over combinations of the `N` items taken `r` at a time (by a factor of `r!`).
- The user interface of `next_permutation` is potentially expensive: for each iteration the algorithm must do a search for the next iteration. When iterating `N` items taken `r` at a time, and when the number of iterations is far less than `N!` (as it will be for many practical problems), then the time spent finding the next iteration using a `next_permutation`-style interface can completely swamp the time you spend actually visiting each permutation.
- To use `next_permutation`, the sequence must be LessThanComparable and in sorted order. These requirements can be inconvenient, even impractical, and are completely unnecessary.

Below is a solution to each of these problems and more. The following generic algorithms permit a client to visit every combination or permuation of a sequence of length `N`, `r` items at time.

>     template <class BidirIter, class Function>
>     Function
>     for_each_permutation(BidirIter first,
>                          BidirIter mid,
>                          BidirIter last,
>                          Function f);

>     template <class BidirIter, class Function>
>     Function
>     for_each_reversible_permutation(BidirIter first,
>                                     BidirIter mid,
>                                     BidirIter last,
>                                     Function f);

>     template <class BidirIter, class Function>
>     Function
>     for_each_circular_permutation(BidirIter first,
>                                   BidirIter mid,
>                                   BidirIter last,
>                                   Function f);

>     template <class BidirIter, class Function>
>     Function
>     for_each_reversible_circular_permutation(BidirIter first,
>                                              BidirIter mid,
>                                              BidirIter last,
>                                              Function f);

>     template <class BidirIter, class Function>
>     Function
>     for_each_combination(BidirIter first,
>                          BidirIter mid,
>                          BidirIter last,
>                          Function f);

These each follow a `for_each` style: The algorithm calls a user supplied function object for each combination/permutation in the sequence: `f(begin, end)`. That function object can of course maintain state. The sequence need not be sorted, nor even contain unique objects. The algorithms do not consider the value of the sequence elements at all. That is, the element type need not support `LessThanComparable` nor `EqualityComparable`. Furthermore the algorithms follow three additional rules:

1. On normal (non-exceptional) completion, the sequence is always left in the original order.

2. The functor is always called with `[first, mid)`. This enables the functor to also access the elements not in the sequence if it is aware of the sequence: `[mid, last)`. This can come in handy when dealing with nested combination/permutation problems where for each permutation you also need to compute combinations and/or permutations on those elements not selected.

3. The functor should return `true` or `false`:

   - `true` if the functor wishes to break out of the `for_each_` loop.
   - Otherwise `false`.

The following generic algorithms take a (preferably unsigned) integral type and return the number of combinations or permutations that exist. Traditionally these functions represent functions such as `nCr` and `nPr`. This API breaks with tradition concerning the definition of `n`. These functions compute: `d1+d2Cd1`, and `d1+d2Pd1`, and the related variations for reversible and circular permuations. The rationale for this API is to avoid invalid inputs. For example if we input `n` and `r` from `nCr`, then we would have to check to make sure that the precondition `n ≥ r` is true, and if not throw an `invalid_argument` exception. But with the inputs `d1` and `d2`, which represent `distance(first, mid)` and `distance(mid, last)` respectively, there is no opportunity for invalid inputs as long as we stick to unsigned integral types. However overflow is a very real possibility. And if signed integral types are input (or a type emulating signed integral types), then negative arguments will result in an `invalid_argument` exception.

>     template <class UInt>
>     UInt
>     count_each_combination(UInt d1, UInt d2);

>     template <class UInt>
>     UInt
>     count_each_permutation(UInt d1, UInt d2);

>     template <class UInt>
>     UInt
>     count_each_circular_permutation(UInt d1, UInt d2);

>     template <class UInt>
>     UInt
>     count_each_reversible_permutation(UInt d1, UInt d2);

>     template <class UInt>
>     UInt
>     count_each_reversible_circular_permutation(UInt d1, UInt d2);

Each of the above algorithms avoids intermediate overflow. That is, if the final answer is representable as a `UInt`, then they will return the correct answer. Otherwise they will throw a `std::overflow_error`. This noisy overflow protection is necessary as these functions can easily overflow. For example `count_each_combination(33ull, 34ull)` returns 14,226,520,737,620,288,370. But `count_each_combination(33ull, 35ull)` overflows for a 64 bit `unsigned long long`. Without overflow protection, the returned result will look quite reasonable to the casual observer and overflow is likely to happen accidentally, go unnoticed, and cause further problems in program logic which will be more difficult to diagnose.

Furthermore the following convenience functions are provided in order to more easily "preflight" ranges sent to the `for_each_*` algorithms. The reason that the `UInt` overloads of these algorithms exist is so that you don't have to create a range to compute `3000C2`. Instead you can simply call `count_each_combination(2ull, 2998ull)` (for example).

>     template <class BidirIter>
>     std::uintmax_t
>     count_each_combination(BidirIter first,
>                            BidirIter mid,
>                            BidirIter last);

>     template <class BidirIter>
>     std::uintmax_t
>     count_each_permutation(BidirIter first,
>                            BidirIter mid,
>                            BidirIter last);

>     template <class BidirIter>
>     std::uintmax_t
>     count_each_circular_permutation(BidirIter first,
>                                     BidirIter mid,
>                                     BidirIter last);

>     template <class BidirIter>
>     std::uintmax_t
>     count_each_reversible_permutation(BidirIter first,
>                                       BidirIter mid,
>                                       BidirIter last);

>     template <class BidirIter>
>     std::uintmax_t
>     count_each_reversible_circular_permutation(BidirIter first,
>                                                BidirIter mid,
>                                                BidirIter last);

## Examples

Below an example simply fills a vector with consecutive integers, and calls `for_each_permutation` on a functor that will print out the permutation. The functor will also print out items not in the permutation after a trailing `'|'`. The functor also counts the number of permutations visited so that the client can query that amount after the call to `for_each_permutation`.

>     #include <iostream>
>     #include <vector>
>     #include <numeric>
>     #include <cstdint>
>     #include <cassert>

>     // print out a range separated by commas,
>     //    return number of values printed.
>     template <class It>
>     unsigned
>     display(It begin, It end)
>     {
>         unsigned r = 0;
>         if (begin != end)
>         {
>             std::cout << *begin;
>             ++r;
>             for (++begin; begin != end; ++begin)
>             {
>                 std::cout << ", " << *begin;
>                 ++r;
>             }
>         }
>         return r;
>     }

>     // functor called for each permutation
>     class f
>     {
>         unsigned len;
>         std::uint64_t count;
>     public:
>         explicit f(unsigned l) : len(l), count(0) {}

>         template <class It>
>             bool operator()(It first, It last)  // called for each permutation
>             {
>                 // count the number of times this is called
>                 ++count;
>                 // print out [first, mid) surrounded with [ ... ]
>                 std::cout << "[ ";
>                 unsigned r = display(first, last);
>                 // If [mid, last) is not empty, then print it out too
>                 //     prefixed by " | "
>                 if (r < len)
>                 {
>                     std::cout << " | ";
>                     display(last, std::next(last, len - r));
>                 }
>                 std::cout << " ]\n";
>                 return false;  // Don't break out of the loop
>             }

>         operator std::uint64_t() const {return count;}
>     };

>     int main()
>     {
>         const int r = 3;
>         const int n = 5;
>         std::vector<int> v(n);
>         std::iota(v.begin(), v.end(), 0);
>         std::uint64_t count = for_each_permutation(v.begin(),
>                                                    v.begin() + r,
>                                                    v.end(),
>                                                    f(v.size()));
>         // print out "---" to the correct length for the above output
>         unsigned e = 3 * r + 2;
>         if (r < v.size())
>             e += 1 + 3 * (v.size() - r);
>         for (unsigned i = 0; i < e; ++i)
>             std::cout << '-';
>         // print out the permuted vector to show that it has the original order
>         std::cout << "\n[ ";
>         display(v.begin(), v.end());
>         std::cout << " ]\n";
>         // sanity check
>         assert(count == count_each_permutation(v.begin(), v.begin() + r, v.end()));
>         // print out summary of what has happened,
>         //   using 'count' from functor state returned from for_each_permutation algorithm.
>         std::cout << "Found " << count << " permutations of " << v.size()
>                   << " objects taken " << r << " at a time.\n";
>     }

And this is the output of this program:

>     [ 0, 1, 2 | 3, 4 ]
>     [ 0, 2, 1 | 3, 4 ]
>     [ 1, 0, 2 | 3, 4 ]
>     [ 1, 2, 0 | 3, 4 ]
>     [ 2, 0, 1 | 3, 4 ]
>     [ 2, 1, 0 | 3, 4 ]
>     [ 0, 1, 3 | 2, 4 ]
>     [ 0, 3, 1 | 2, 4 ]
>     [ 1, 0, 3 | 2, 4 ]
>     [ 1, 3, 0 | 2, 4 ]
>     [ 3, 0, 1 | 2, 4 ]
>     [ 3, 1, 0 | 2, 4 ]
>     [ 0, 1, 4 | 2, 3 ]
>     [ 0, 4, 1 | 2, 3 ]
>     [ 1, 0, 4 | 2, 3 ]
>     [ 1, 4, 0 | 2, 3 ]
>     [ 4, 0, 1 | 2, 3 ]
>     [ 4, 1, 0 | 2, 3 ]
>     [ 0, 2, 3 | 1, 4 ]
>     [ 0, 3, 2 | 1, 4 ]
>     [ 2, 0, 3 | 1, 4 ]
>     [ 2, 3, 0 | 1, 4 ]
>     [ 3, 0, 2 | 1, 4 ]
>     [ 3, 2, 0 | 1, 4 ]
>     [ 0, 2, 4 | 1, 3 ]
>     [ 0, 4, 2 | 1, 3 ]
>     [ 2, 0, 4 | 1, 3 ]
>     [ 2, 4, 0 | 1, 3 ]
>     [ 4, 0, 2 | 1, 3 ]
>     [ 4, 2, 0 | 1, 3 ]
>     [ 0, 3, 4 | 1, 2 ]
>     [ 0, 4, 3 | 1, 2 ]
>     [ 3, 0, 4 | 1, 2 ]
>     [ 3, 4, 0 | 1, 2 ]
>     [ 4, 0, 3 | 1, 2 ]
>     [ 4, 3, 0 | 1, 2 ]
>     [ 1, 2, 3 | 0, 4 ]
>     [ 1, 3, 2 | 0, 4 ]
>     [ 2, 1, 3 | 0, 4 ]
>     [ 2, 3, 1 | 0, 4 ]
>     [ 3, 1, 2 | 0, 4 ]
>     [ 3, 2, 1 | 0, 4 ]
>     [ 1, 2, 4 | 0, 3 ]
>     [ 1, 4, 2 | 0, 3 ]
>     [ 2, 1, 4 | 0, 3 ]
>     [ 2, 4, 1 | 0, 3 ]
>     [ 4, 1, 2 | 0, 3 ]
>     [ 4, 2, 1 | 0, 3 ]
>     [ 1, 3, 4 | 0, 2 ]
>     [ 1, 4, 3 | 0, 2 ]
>     [ 3, 1, 4 | 0, 2 ]
>     [ 3, 4, 1 | 0, 2 ]
>     [ 4, 1, 3 | 0, 2 ]
>     [ 4, 3, 1 | 0, 2 ]
>     [ 2, 3, 4 | 0, 1 ]
>     [ 2, 4, 3 | 0, 1 ]
>     [ 3, 2, 4 | 0, 1 ]
>     [ 3, 4, 2 | 0, 1 ]
>     [ 4, 2, 3 | 0, 1 ]
>     [ 4, 3, 2 | 0, 1 ]
>     ------------------
>     [ 0, 1, 2, 3, 4 ]
>     Found 60 permutations of 5 objects taken 3 at a time.

The above list can be cut in half by instead calling:

>     for_each_reversible_permutation(v.begin(), v.begin() + r, v.end(), f(v.size()));

>     [ 0, 1, 2 | 3, 4 ]
>     [ 0, 2, 1 | 3, 4 ]
>     [ 1, 0, 2 | 3, 4 ]
>     [ 0, 1, 3 | 2, 4 ]
>     [ 0, 3, 1 | 2, 4 ]
>     [ 1, 0, 3 | 2, 4 ]
>     [ 0, 1, 4 | 2, 3 ]
>     [ 0, 4, 1 | 2, 3 ]
>     [ 1, 0, 4 | 2, 3 ]
>     [ 0, 2, 3 | 1, 4 ]
>     [ 0, 3, 2 | 1, 4 ]
>     [ 2, 0, 3 | 1, 4 ]
>     [ 0, 2, 4 | 1, 3 ]
>     [ 0, 4, 2 | 1, 3 ]
>     [ 2, 0, 4 | 1, 3 ]
>     [ 0, 3, 4 | 1, 2 ]
>     [ 0, 4, 3 | 1, 2 ]
>     [ 3, 0, 4 | 1, 2 ]
>     [ 1, 2, 3 | 0, 4 ]
>     [ 1, 3, 2 | 0, 4 ]
>     [ 2, 1, 3 | 0, 4 ]
>     [ 1, 2, 4 | 0, 3 ]
>     [ 1, 4, 2 | 0, 3 ]
>     [ 2, 1, 4 | 0, 3 ]
>     [ 1, 3, 4 | 0, 2 ]
>     [ 1, 4, 3 | 0, 2 ]
>     [ 3, 1, 4 | 0, 2 ]
>     [ 2, 3, 4 | 0, 1 ]
>     [ 2, 4, 3 | 0, 1 ]
>     [ 3, 2, 4 | 0, 1 ]
>     ------------------
>     [ 0, 1, 2, 3, 4 ]
>     Found 30 permutations of 5 objects taken 3 at a time.

For example `[ 2, 1, 0 ]` is not found in the above list.

By instead calling:

>     for_each_circular_permutation(v.begin(), v.begin() + r, v.end(), f(v.size()));

the original list can be cut by a third:

>     [ 0, 1, 2 | 3, 4 ]
>     [ 0, 2, 1 | 3, 4 ]
>     [ 0, 1, 3 | 2, 4 ]
>     [ 0, 3, 1 | 2, 4 ]
>     [ 0, 1, 4 | 2, 3 ]
>     [ 0, 4, 1 | 2, 3 ]
>     [ 0, 2, 3 | 1, 4 ]
>     [ 0, 3, 2 | 1, 4 ]
>     [ 0, 2, 4 | 1, 3 ]
>     [ 0, 4, 2 | 1, 3 ]
>     [ 0, 3, 4 | 1, 2 ]
>     [ 0, 4, 3 | 1, 2 ]
>     [ 1, 2, 3 | 0, 4 ]
>     [ 1, 3, 2 | 0, 4 ]
>     [ 1, 2, 4 | 0, 3 ]
>     [ 1, 4, 2 | 0, 3 ]
>     [ 1, 3, 4 | 0, 2 ]
>     [ 1, 4, 3 | 0, 2 ]
>     [ 2, 3, 4 | 0, 1 ]
>     [ 2, 4, 3 | 0, 1 ]
>     ------------------
>     [ 0, 1, 2, 3, 4 ]
>     Found 20 permutations of 5 objects taken 3 at a time.

For example you will not find the following in the above list:

>     [ 1, 2, 0 ]  // rotate(0, 1, 3) of permutation 1
>     [ 2, 0, 1 ]  // rotate(0, 2, 3) of permutation 1

And if your circular permutations are also reversible, your list (and time spent) can be halved again:

>     for_each_reversible_circular_permutation(v.begin(), v.begin() + r, v.end(), f(v.size()));

>     [ 0, 1, 2 | 3, 4 ]
>     [ 0, 1, 3 | 2, 4 ]
>     [ 0, 1, 4 | 2, 3 ]
>     [ 0, 2, 3 | 1, 4 ]
>     [ 0, 2, 4 | 1, 3 ]
>     [ 0, 3, 4 | 1, 2 ]
>     [ 1, 2, 3 | 0, 4 ]
>     [ 1, 2, 4 | 0, 3 ]
>     [ 1, 3, 4 | 0, 2 ]
>     [ 2, 3, 4 | 0, 1 ]
>     ------------------
>     [ 0, 1, 2, 3, 4 ]
>     Found 10 permutations of 5 objects taken 3 at a time.

For example you will not find the following in the above list:

>     [ 2, 1, 0 ]  // reverse(0, 3) of permutation(1)
>     [ 1, 2, 0 ]  // rotate(0, 1, 3) of permutation(1)
>     [ 0, 2, 1 ]  // reverse of rotate(0, 1, 3) of permutation(1)
>     [ 2, 0, 1 ]  // rotate(0, 2, 3) of permutation(1)
>     [ 1, 0, 2 ]  // reverse of rotate(0, 2, 3) of permutation(1)

When `r` is 3 or less, then reversible circular permutations are the exact same as combinations. In this case use of `for_each_combination` should be preferred as it will be a little more efficient. Additionally when `r` is 2 or less, `for_each_combination` produces the same result as `for_each_circular_permutation` and `for_each_reversible_permutation`. When `r == 1`, all five algorithms produce the same `N` permutations. When `r == 0`, all five algorithms call the functor once with the empty range `[first, first)`.

## Performance Considerations

Hervé Brönnimann published N2639 proposing functionality somewhat similar as to what is outlined herein, including:

>     template <class BidirIter>
>     bool
>     next_partial_permutation(BidirIter first,
>                              BidirIter mid,
>                              BidirIter last);

>     template <class BidirIter >
>     bool
>     next_combination(BidirIter first,
>                      BidirIter mid,
>                      BidirIter last);

This interface follows the style of the existing `std::next_permutation` algorithm. It is the inverse of the `for_each` style: The client calls the functor directly, and then calls the algorithm to find the next iteration.

The problem with this interface is that it can get expensive to find the next iteration. For example when calling `for_each_permutation` and `next_partial_permutation` with `r == 4` and varying `N` from 4 to 100, the time to iterate through the permutations skyrockets for `next_partial_permutation`, but not for `for_each_permutation`. By the time `N == 100`, `for_each_permutation` is running over 137 times faster than `next_partial_permutation` which takes 20 seconds to do what `for_each_permutation` accomplishes in well under one sixth of a second. This trend rapidly gets worse as `N` grows.

The same performance comparison can be made between `next_combination` and `for_each_combination`. It should be stressed that this isn't a lack of quality or care put into the N2639 implementation. I've studied that implementation carefully and consider it very high quality. It is simply that the number of comparisons that need to be done to find out which swaps need to be done gets outrageously expensive. The number of swaps actually performed in both algorithms is approximately the same. At `N == 100` `for_each_combination` is running about 14 times faster than `next_combination`. And that discrepancy only grows as the number of combinations increases.

## Synopsis

>     // Integral-based count_each_*

>     template <class UInt>
>     UInt
>     count_each_permutation(UInt d1, UInt d2);

>     template <class UInt>
>     UInt
>     count_each_reversible_permutation(UInt d1, UInt d2);

>     template <class UInt>
>     UInt
>     count_each_circular_permutation(UInt d1, UInt d2);

>     template <class UInt>
>     UInt
>     count_each_reversible_circular_permutation(UInt d1, UInt d2);

>     template <class UInt>
>     UInt
>     count_each_combination(UInt d1, UInt d2);

>     // Iterator-based count_each_*

>     template <class BidirIter>
>     std::uintmax_t
>     count_each_permutation(BidirIter first,
>                            BidirIter mid,
>                            BidirIter last);

>     template <class BidirIter>
>     std::uintmax_t
>     count_each_reversible_permutation(BidirIter first,
>                                       BidirIter mid,
>                                       BidirIter last);

>     template <class BidirIter>
>     std::uintmax_t
>     count_each_circular_permutation(BidirIter first,
>                                     BidirIter mid,
>                                     BidirIter last);

>     template <class BidirIter>
>     std::uintmax_t
>     count_each_reversible_circular_permutation(BidirIter first,
>                                                BidirIter mid,
>                                                BidirIter last);

>     template <class BidirIter>
>     std::uintmax_t
>     count_each_combination(BidirIter first,
>                            BidirIter mid,
>                            BidirIter last);

>     // Iterator-based for_each_* algorithms

>     template <class BidirIter, class Function>
>     Function
>     for_each_permutation(BidirIter first,
>                          BidirIter mid,
>                          BidirIter last,
>                          Function f);

>     template <class BidirIter, class Function>
>     Function
>     for_each_reversible_permutation(BidirIter first,
>                                     BidirIter mid,
>                                     BidirIter last,
>                                     Function f);

>     template <class BidirIter, class Function>
>     Function
>     for_each_circular_permutation(BidirIter first,
>                                   BidirIter mid,
>                                   BidirIter last,
>                                   Function f);

>     template <class BidirIter, class Function>
>     Function
>     for_each_reversible_circular_permutation(BidirIter first,
>                                              BidirIter mid,
>                                              BidirIter last,
>                                              Function f);

>     template <class BidirIter, class Function>
>     Function
>     for_each_combination(BidirIter first,
>                          BidirIter mid,
>                          BidirIter last,
>                          Function f);

## Specification

Remarks: In this section a post-fix `!` indicates a factorial operator and has higher precedence than any other operator.

>     template <class UInt>
>     UInt
>     count_each_permutation(UInt d1, UInt d2);

> > Requires: `Uint` is an integral type or a type emulating an integral type.

> > Returns: `(d1 + d2)!/d2!`.

> > Throws: If the computed value is not representable in the type `UInt`, throws `std::overflow_error`. If `d1 < UInt(0)` or `d2 < UInt(0)`, throws `std::invalid_argument`.

> > Remarks: If the computed value is representable in the type `UInt`, returns the correct value. This algorithm avoids intermediate overflow.

>     template <class UInt>
>     UInt
>     count_each_reversible_permutation(UInt d1, UInt d2);

> > Requires: `Uint` is an integral type or a type emulating an integral type.

> > Returns: If `d1 <= 1` returns `(d1 + d2)!/d2!`. Else returns `(d1 + d2)!/(2*d2!)`.

> > Throws: If the computed value is not representable in the type `UInt`, throws `std::overflow_error`. If `d1 < UInt(0)` or `d2 < UInt(0)`, throws `std::invalid_argument`.

> > Remarks: If the computed value is representable in the type `UInt`, returns the correct value. This algorithm avoids intermediate overflow.

>     template <class UInt>
>     UInt
>     count_each_circular_permutation(UInt d1, UInt d2);

> > Requires: `Uint` is an integral type or a type emulating an integral type.

> > Returns: If `d1 == 0` returns 1. Else returns `(d1 + d2)!/(d1*d2!)`.

> > Throws: If the computed value is not representable in the type `UInt`, throws `std::overflow_error`. If `d1 < UInt(0)` or `d2 < UInt(0)`, throws `std::invalid_argument`.

> > Remarks: If the computed value is representable in the type `UInt`, returns the correct value. This algorithm avoids intermediate overflow.

>     template <class UInt>
>     UInt
>     count_each_reversible_circular_permutation(UInt d1, UInt d2);

> > Requires: `Uint` is an integral type or a type emulating an integral type.

> > Returns: If `d1 == 0` returns 1. Else if `d1 <= 2` returns `(d1 + d2)!/(d1*d2!)`. Else returns `(d1 + d2)!/(2*d1*d2!)`.

> > Throws: If the computed value is not representable in the type `UInt`, throws `std::overflow_error`. If `d1 < UInt(0)` or `d2 < UInt(0)`, throws `std::invalid_argument`.

> > Remarks: If the computed value is representable in the type `UInt`, returns the correct value. This algorithm avoids intermediate overflow.

>     template <class UInt>
>     UInt
>     count_each_combination(UInt d1, UInt d2);

> > Requires: `Uint` is an integral type or a type emulating an integral type.

> > Returns: `(d1 + d2)!/(d1!*d2!)`.

> > Throws: If the computed value is not representable in the type `UInt`, throws `std::overflow_error`. If `d1 < UInt(0)` or `d2 < UInt(0)`, throws `std::invalid_argument`.

> > Remarks: If the computed value is representable in the type `UInt`, returns the correct value. This algorithm avoids intermediate overflow.

>     template <class FwdIter>
>     std::uintmax_t
>     count_each_permutation(FwdIter first,
>                                FwdIter mid,
>                                FwdIter last);

> > Requires: `[first, mid)` and `[mid, last)` are valid ranges.

> > Returns: `count_each_permutation<std::uintmax_t>(std::distance(first, mid), std::distance(mid, last))`.

>     template <class FwdIter>
>     std::uintmax_t
>     count_each_reversible_permutation(FwdIter first,
>                                           FwdIter mid,
>                                           FwdIter last);

> > Requires: `[first, mid)` and `[mid, last)` are valid ranges.

> > Returns: `count_each_reversible_permutation<std::uintmax_t>(std::distance(first, mid), std::distance(mid, last))`.

>     template <class FwdIter>
>     std::uintmax_t
>     count_each_circular_permutation(FwdIter first,
>                                         FwdIter mid,
>                                         FwdIter last);

> > Requires: `[first, mid)` and `[mid, last)` are valid ranges.

> > Returns: `count_each_circular_permutation<std::uintmax_t>(std::distance(first, mid), std::distance(mid, last))`.

>     template <class FwdIter>
>     std::uintmax_t
>     count_each_reversible_circular_permutation(FwdIter first,
>                                                    FwdIter mid,
>                                                    FwdIter last);

> > Requires: `[first, mid)` and `[mid, last)` are valid ranges.

> > Returns: `count_each_reversible_circular_permutation<std::uintmax_t>(std::distance(first, mid), std::distance(mid, last))`.

>     template <class FwdIter>
>     std::uintmax_t
>     count_each_combination(FwdIter first,
>                                FwdIter mid,
>                                FwdIter last);

> > Requires: `[first, mid)` and `[mid, last)` are valid ranges.

> > Returns: `count_each_combination<std::uintmax_t>(std::distance(first, mid), std::distance(mid, last))`.

>     template <class BidirIter, class Function>
>     Function
>     for_each_permutation(BidirIter first,
>                          BidirIter mid,
>                          BidirIter last,
>                          Function f);

> > Requires:

> > - The type of `*first` shall satisfy the requirements of `Swappable`, `MoveConstructible` and `MoveAssignable`.
> > - `[first, mid)` and `[mid, last)` are valid ranges.
> > - `Function` shall meet the requirements of `MoveConstructible` and `MoveAssignable`.
> > - `f` is callable as `f(first, mid)` and returns a type contextually convertible to `bool`.

> > Effects: Repeatedly permutes the range `[first, last)` such that the range `[first, mid)` represents each permutation of the values in `[first, last)` taken `distance(first, mid)` at a time. For each permutation calls `f(first, mid)`. On each call, the range `[mid, last)` holds the values not in the current permutation. If `f` returns `true` then returns immediately without permuting the sequence any futher. Otherwise, after the last call to `f`, and prior to returning, the range `[first, last)` is restored to its original order. [Note: If `f` always returns `false` it is called `count_each_permutation(first, mid, last)` times. — end note]

> > Returns: `f`.

> > Notes: The type referenced by `*first` need not be `EqualityComparable` nor `LessThanComparable`. The input range need not be sorted. The algorithm does not take the values in the range `[first, last)` into account in any way.

>     template <class BidirIter, class Function>
>     Function
>     for_each_reversible_permutation(BidirIter first,
>                                     BidirIter mid,
>                                     BidirIter last,
>                                     Function f);

> > Requires:

> > - The type of `*first` shall satisfy the requirements of `Swappable`, `MoveConstructible` and `MoveAssignable`.
> > - `[first, mid)` and `[mid, last)` are valid ranges.
> > - `Function` shall meet the requirements of `MoveConstructible` and `MoveAssignable`.
> > - `f` is callable as `f(first, mid)` and returns a type contextually convertible to `bool`.

> > Effects: Repeatedly permutes the range `[first, last)` such that the range `[first, mid)` represents each permutation of the values in `[first, last)` taken `distance(first, mid)` at a time, except that `f` is never called with the reverse of a permutation which has been previously called. For each permutation calls `f(first, mid)`. On each call, the range `[mid, last)` holds the values not in the current permutation. If `f` returns `true` then returns immediately without permuting the sequence any futher. Otherwise, after the last call to `f`, and prior to returning, the range `[first, last)` is restored to its original order. [Note: If `f` always returns `false` it is called `count_each_reversible_permutation(first, mid, last)` times. — end note]

> > Returns: `f`.

> > Notes: The type referenced by `*first` need not be `EqualityComparable` nor `LessThanComparable`. The input range need not be sorted. The algorithm does not take the values in the range `[first, last)` into account in any way.

>     template <class BidirIter, class Function>
>     Function
>     for_each_circular_permutation(BidirIter first,
>                                   BidirIter mid,
>                                   BidirIter last,
>                                   Function f);

> > Requires:

> > - The type of `*first` shall satisfy the requirements of `Swappable`, `MoveConstructible` and `MoveAssignable`.
> > - `[first, mid)` and `[mid, last)` are valid ranges.
> > - `Function` shall meet the requirements of `MoveConstructible` and `MoveAssignable`.
> > - `f` is callable as `f(first, mid)` and returns a type contextually convertible to `bool`.

> > Effects: Repeatedly permutes the range `[first, last)` such that the range `[first, mid)` represents each permutation of the values in `[first, last)` taken `distance(first, mid)` at a time, except that `f` is never called with a circular permutation which has been previously called. For each permutation calls `f(first, mid)`. On each call, the range `[mid, last)` holds the values not in the current permutation. If `f` returns `true` then returns immediately without permuting the sequence any futher. Otherwise, after the last call to `f`, and prior to returning, the range `[first, last)` is restored to its original order. [Note: If `f` always returns `false` it is called `count_each_circular_permutation(first, mid, last)` times. — end note]

> > Returns: `f`.

> > Notes: The type referenced by `*first` need not be `EqualityComparable` nor `LessThanComparable`. The input range need not be sorted. The algorithm does not take the values in the range `[first, last)` into account in any way.

>     template <class BidirIter, class Function>
>     Function
>     for_each_reversible_circular_permutation(BidirIter first,
>                                              BidirIter mid,
>                                              BidirIter last,
>                                              Function f);

> > Requires:

> > - The type of `*first` shall satisfy the requirements of `Swappable`, `MoveConstructible` and `MoveAssignable`.
> > - `[first, mid)` and `[mid, last)` are valid ranges.
> > - `Function` shall meet the requirements of `MoveConstructible` and `MoveAssignable`.
> > - `f` is callable as `f(first, mid)` and returns a type contextually convertible to `bool`.

> > Effects: Repeatedly permutes the range `[first, last)` such that the range `[first, mid)` represents each permutation of the values in `[first, last)` taken `distance(first, mid)` at a time, except that `f` is never called with a circular permutation which has been previously called, or the reverse of that permutation. For each permutation calls `f(first, mid)`. On each call, the range `[mid, last)` holds the values not in the current permutation. If `f` returns `true` then returns immediately without permuting the sequence any futher. Otherwise, after the last call to `f`, and prior to returning, the range `[first, last)` is restored to its original order. [Note: If `f` always returns `false` it is called `count_each_reversible_circular_permutation(first, mid, last)` times. — end note]

> > Returns: `f`.

> > Notes: The type referenced by `*first` need not be `EqualityComparable` nor `LessThanComparable`. The input range need not be sorted. The algorithm does not take the values in the range `[first, last)` into account in any way.

>     template <class BidirIter, class Function>
>     Function
>     for_each_combination(BidirIter first,
>                          BidirIter mid,
>                          BidirIter last,
>                          Function f);

> > Requires:

> > - The type of `*first` shall satisfy the requirements of `Swappable`, `MoveConstructible` and `MoveAssignable`.
> > - `[first, mid)` and `[mid, last)` are valid ranges.
> > - `Function` shall meet the requirements of `MoveConstructible` and `MoveAssignable`.
> > - `f` is callable as `f(first, mid)` and returns a type contextually convertible to `bool`.

> > Effects: Repeatedly permutes the range `[first, last)` such that the range `[first, mid)` represents each combination of the values in `[first, last)` taken `distance(first, mid)` at a time. For each permutation calls `f(first, mid)`. On each call, the range `[mid, last)` holds the values not in the current permutation. If `f` returns `true` then returns immediately without permuting the sequence any futher. Otherwise, after the last call to `f`, and prior to returning, the range `[first, last)` is restored to its original order. [Note: If `f` always returns `false` it is called `count_each_combination(first, mid, last)` times. — end note]

> > Returns: `f`.

> > Notes: The type referenced by `*first` need not be `EqualityComparable` nor `LessThanComparable`. The input range need not be sorted. The algorithm does not take the values in the range `[first, last)` into account in any way.

Oh, and `gcd`. I'm tired of reinventing it.

>     template
>     UInt
>     gcd(UInt x, UInt y) noexcept;

> > Requires: `Uint` is an integral type or a type emulating an integral type. `x` and `y` are positive.

> > Returns: The greatest common divisor of `x` and `y`.

## Implementation

Here is the code.

>     //  (C) Copyright Howard Hinnant 2005-2011.
>     //  Use, modification and distribution are subject to the Boost Software License,
>     //  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
>     //  http://www.boost.org/LICENSE_1_0.txt).
>     //
>     //  See http://www.boost.org/libs/type_traits for most recent version including documentation.

>     //  Details are in namespace detail.  Every effort has been made to make
>     //  combine_discontinuous and permute as fast as possible.  They minimize the number
>     //  of swaps that are performed. Everything else builds on these two primitives.
>     //  The most complicated algorithm is for_each_reversible_permutation.  But it
>     //  builds on combine_discontinuous and permute and I believe represents a minimum
>     //  number of swaps.  Without care, algorithms such as for_each_reversible_permutation
>     //  will take longer than for_each_permutation instead of the intended half the time.

>     //  Speed is everything.  Lest you could just use std::next_permutation and manually
>     //  eliminate duplicate permutations.  If the implementation fails in being orders
>     //  of magnitude faster than that, then it has failed miserably.

>     #include <iterator>
>     #include <algorithm>
>     #include <cstdint>
>     #include <limits>
>     #include <stdexcept>

>     namespace detail
>     {

>     // Rotates two discontinuous ranges to put *first2 where *first1 is.
>     //     If last1 == first2 this would be equivalent to rotate(first1, first2, last2),
>     //     but instead the rotate "jumps" over the discontinuity [last1, first2) -
>     //     which need not be a valid range.
>     //     In order to make it faster, the length of [first1, last1) is passed in as d1,
>     //     and d2 must be the length of [first2, last2).
>     //  In a perfect world the d1 > d2 case would have used swap_ranges and
>     //     reverse_iterator, but reverse_iterator is too inefficient.
>     template <class BidirIter>
>     void
>     rotate_discontinuous(BidirIter first1, BidirIter last1,
>                          typename std::iterator_traits<BidirIter>::difference_type d1,
>                          BidirIter first2, BidirIter last2,
>                          typename std::iterator_traits<BidirIter>::difference_type d2)
>     {
>         using std::swap;
>         if (d1 <= d2)
>             std::rotate(first2, std::swap_ranges(first1, last1, first2), last2);
>         else
>         {
>             BidirIter i1 = last1;
>             while (first2 != last2)
>                 swap(*--i1, *--last2);
>             std::rotate(first1, i1, last1);
>         }
>     }

>     // Rotates the three discontinuous ranges to put *first2 where *first1 is.
>     // Just like rotate_discontinuous, except the second range is now represented by
>     //    two discontinuous ranges: [first2, last2) + [first3, last3).
>     template <class BidirIter>
>     void
>     rotate_discontinuous3(BidirIter first1, BidirIter last1,
>                           typename std::iterator_traits<BidirIter>::difference_type d1,
>                           BidirIter first2, BidirIter last2,
>                           typename std::iterator_traits<BidirIter>::difference_type d2,
>                           BidirIter first3, BidirIter last3,
>                           typename std::iterator_traits<BidirIter>::difference_type d3)
>     {
>         rotate_discontinuous(first1, last1, d1, first2, last2, d2);
>         if (d1 <= d2)
>             rotate_discontinuous(std::next(first2, d2 - d1), last2, d1, first3, last3, d3);
>         else
>         {
>             rotate_discontinuous(std::next(first1, d2), last1, d1 - d2, first3, last3, d3);
>             rotate_discontinuous(first2, last2, d2, first3, last3, d3);
>         }
>     }

>     // Call f() for each combination of the elements [first1, last1) + [first2, last2)
>     //    swapped/rotated into the range [first1, last1).  As long as f() returns
>     //    false, continue for every combination and then return [first1, last1) and
>     //    [first2, last2) to their original state.  If f() returns true, return
>     //    immediately.
>     //  Does the absolute mininum amount of swapping to accomplish its task.
>     //  If f() always returns false it will be called (d1+d2)!/(d1!*d2!) times.
>     template <class BidirIter, class Function>
>     bool
>     combine_discontinuous(BidirIter first1, BidirIter last1,
>                           typename std::iterator_traits<BidirIter>::difference_type d1,
>                           BidirIter first2, BidirIter last2,
>                           typename std::iterator_traits<BidirIter>::difference_type d2,
>                           Function& f,
>                           typename std::iterator_traits<BidirIter>::difference_type d = 0)
>     {
>         typedef typename std::iterator_traits<BidirIter>::difference_type D;
>         using std::swap;
>         if (d1 == 0 || d2 == 0)
>             return f();
>         if (d1 == 1)
>         {
>             for (BidirIter i2 = first2; i2 != last2; ++i2)
>             {
>                 if (f())
>                     return true;
>                 swap(*first1, *i2);
>             }
>         }
>         else
>         {
>             BidirIter f1p = std::next(first1);
>             BidirIter i2 = first2;
>             for (D d22 = d2; i2 != last2; ++i2, --d22)
>             {
>                 if (combine_discontinuous(f1p, last1, d1-1, i2, last2, d22, f, d+1))
>                     return true;
>                 swap(*first1, *i2);
>             }
>         }
>         if (f())
>             return true;
>         if (d != 0)
>             rotate_discontinuous(first1, last1, d1, std::next(first2), last2, d2-1);
>         else
>             rotate_discontinuous(first1, last1, d1, first2, last2, d2);
>         return false;
>     }

>     // A binder for binding arguments to call combine_discontinuous
>     template <class Function, class BidirIter>
>     class call_combine_discontinuous
>     {
>         typedef typename std::iterator_traits<BidirIter>::difference_type D;
>         Function f_;
>         BidirIter first1_;
>         BidirIter last1_;
>         D d1_;
>         BidirIter first2_;
>         BidirIter last2_;
>         D d2_;

>     public:
>         call_combine_discontinuous(
>                           BidirIter first1, BidirIter last1,
>                           D d1,
>                           BidirIter first2, BidirIter last2,
>                           D d2,
>                           Function& f)
>             : f_(f), first1_(first1), last1_(last1), d1_(d1),
>                      first2_(first2), last2_(last2), d2_(d2) {}

>         bool operator()()
>         {
>             return combine_discontinuous(first1_, last1_, d1_, first2_, last2_, d2_, f_);
>         }
>     };

>     // See combine_discontinuous3
>     template <class BidirIter, class Function>
>     bool
>     combine_discontinuous3_(BidirIter first1, BidirIter last1,
>                             typename std::iterator_traits<BidirIter>::difference_type d1,
>                             BidirIter first2, BidirIter last2,
>                             typename std::iterator_traits<BidirIter>::difference_type d2,
>                             BidirIter first3, BidirIter last3,
>                             typename std::iterator_traits<BidirIter>::difference_type d3,
>                             Function& f,
>                             typename std::iterator_traits<BidirIter>::difference_type d = 0)
>     {
>         typedef typename std::iterator_traits<BidirIter>::difference_type D;
>         using std::swap;
>         if (d1 == 1)
>         {
>             for (BidirIter i2 = first2; i2 != last2; ++i2)
>             {
>                 if (f())
>                     return true;
>                 swap(*first1, *i2);
>             }
>             if (f())
>                 return true;
>             swap(*first1, *std::prev(last2));
>             swap(*first1, *first3);
>             for (BidirIter i2 = std::next(first3); i2 != last3; ++i2)
>             {
>                 if (f())
>                     return true;
>                 swap(*first1, *i2);
>             }
>         }
>         else
>         {
>             BidirIter f1p = std::next(first1);
>             BidirIter i2 = first2;
>             for (D d22 = d2; i2 != last2; ++i2, --d22)
>             {
>                 if (combine_discontinuous3_(f1p, last1, d1-1, i2, last2, d22, first3,
>                                             last3, d3, f, d+1))
>                     return true;
>                 swap(*first1, *i2);
>             }
>             i2 = first3;
>             for (D d22 = d3; i2 != last3; ++i2, --d22)
>             {
>                 if (combine_discontinuous(f1p, last1, d1-1, i2, last3, d22, f, d+1))
>                     return true;
>                 swap(*first1, *i2);
>             }
>         }
>         if (f())
>             return true;
>         if (d1 == 1)
>             swap(*std::prev(last2), *first3);
>         if (d != 0)
>         {
>             if (d2 > 1)
>                 rotate_discontinuous3(first1, last1, d1, std::next(first2), last2, d2-1, first3, last3, d3);
>             else
>                 rotate_discontinuous(first1, last1, d1, first3, last3, d3);
>         }
>         else
>             rotate_discontinuous3(first1, last1, d1, first2, last2, d2, first3, last3, d3);
>         return false;
>     }

>     // Like combine_discontinuous, but swaps/rotates each combination out of
>     //    [first1, last1) + [first2, last2) + [first3, last3) into [first1, last1).
>     //    If f() always returns false, it is called (d1+d2+d3)!/(d1!*(d2+d3)!) times.
>     template <class BidirIter, class Function>
>     bool
>     combine_discontinuous3(BidirIter first1, BidirIter last1,
>                            typename std::iterator_traits<BidirIter>::difference_type d1,
>                            BidirIter first2, BidirIter last2,
>                            typename std::iterator_traits<BidirIter>::difference_type d2,
>                            BidirIter first3, BidirIter last3,
>                            typename std::iterator_traits<BidirIter>::difference_type d3,
>                            Function& f)
>     {
>         typedef call_combine_discontinuous<Function&, BidirIter> F;
>         F fbc(first2, last2, d2, first3, last3, d3, f);  // BC
>         return combine_discontinuous3_(first1, last1, d1, first2, last2, d2, first3, last3, d3, fbc);
>     }

>     // See permute
>     template <class BidirIter, class Function>
>     bool
>     permute_(BidirIter first1, BidirIter last1,
>              typename std::iterator_traits<BidirIter>::difference_type d1,
>              Function& f)
>     {
>         using std::swap;
>         switch (d1)
>         {
>         case 0:
>         case 1:
>             return f();
>         case 2:
>             if (f())
>                 return true;
>             swap(*first1, *std::next(first1));
>             return f();
>         case 3:
>             {
>             if (f())
>                 return true;
>             BidirIter f2 = std::next(first1);
>             BidirIter f3 = std::next(f2);
>             swap(*f2, *f3);
>             if (f())
>                 return true;
>             swap(*first1, *f3);
>             swap(*f2, *f3);
>             if (f())
>                 return true;
>             swap(*f2, *f3);
>             if (f())
>                 return true;
>             swap(*first1, *f2);
>             swap(*f2, *f3);
>             if (f())
>                 return true;
>             swap(*f2, *f3);
>             return f();
>             }
>         }
>         BidirIter fp1 = std::next(first1);
>         for (BidirIter p = fp1; p != last1; ++p)
>         {
>             if (permute_(fp1, last1, d1-1, f))
>                 return true;
>             std::reverse(fp1, last1);
>             swap(*first1, *p);
>         }
>         return permute_(fp1, last1, d1-1, f);
>     }

>     // Calls f() for each permutation of [first1, last1)
>     // Divided into permute and permute_ in a (perhaps futile) attempt to
>     //    squeeze a little more performance out of it.
>     template <class BidirIter, class Function>
>     bool
>     permute(BidirIter first1, BidirIter last1,
>             typename std::iterator_traits<BidirIter>::difference_type d1,
>             Function& f)
>     {
>         using std::swap;
>         switch (d1)
>         {
>         case 0:
>         case 1:
>             return f();
>         case 2:
>             {
>             if (f())
>                 return true;
>             BidirIter i = std::next(first1);
>             swap(*first1, *i);
>             if (f())
>                 return true;
>             swap(*first1, *i);
>             }
>             break;
>         case 3:
>             {
>             if (f())
>                 return true;
>             BidirIter f2 = std::next(first1);
>             BidirIter f3 = std::next(f2);
>             swap(*f2, *f3);
>             if (f())
>                 return true;
>             swap(*first1, *f3);
>             swap(*f2, *f3);
>             if (f())
>                 return true;
>             swap(*f2, *f3);
>             if (f())
>                 return true;
>             swap(*first1, *f2);
>             swap(*f2, *f3);
>             if (f())
>                 return true;
>             swap(*f2, *f3);
>             if (f())
>                 return true;
>             swap(*first1, *f3);
>             }
>             break;
>         default:
>             BidirIter fp1 = std::next(first1);
>             for (BidirIter p = fp1; p != last1; ++p)
>             {
>                 if (permute_(fp1, last1, d1-1, f))
>                     return true;
>                 std::reverse(fp1, last1);
>                 swap(*first1, *p);
>             }
>             if (permute_(fp1, last1, d1-1, f))
>                 return true;
>             std::reverse(first1, last1);
>             break;
>         }
>         return false;
>     }

>     // Creates a functor with no arguments which calls f_(first_, last_).
>     //   Also has a variant that takes two It and ignores them.
>     template <class Function, class It>
>     class bound_range
>     {
>         Function f_;
>         It first_;
>         It last_;
>     public:
>         bound_range(Function f, It first, It last)
>             : f_(f), first_(first), last_(last) {}

>         bool
>         operator()()
>         {
>             return f_(first_, last_);
>         }

>         bool
>         operator()(It, It)
>         {
>             return f_(first_, last_);
>         }
>     };

>     // A binder for binding arguments to call permute
>     template <class Function, class It>
>     class call_permute
>     {
>         typedef typename std::iterator_traits<It>::difference_type D;
>         Function f_;
>         It first_;
>         It last_;
>         D d_;
>     public:
>         call_permute(Function f, It first, It last, D d)
>             : f_(f), first_(first), last_(last), d_(d) {}

>         bool
>         operator()()
>         {
>             return permute(first_, last_, d_, f_);
>         }
>     };

>     }  // detail

>     template <class BidirIter, class Function>
>     Function
>     for_each_combination(BidirIter first, BidirIter mid,
>                          BidirIter last, Function f)
>     {
>         detail::bound_range<Function&, BidirIter> wfunc(f, first, mid);
>         detail::combine_discontinuous(first, mid, std::distance(first, mid),
>                                       mid, last, std::distance(mid, last),
>                                       wfunc);
>         return f;
>     }

>     template <class UInt>
>     UInt
>     gcd(UInt x, UInt y)
>     {
>         while (y != 0)
>         {
>             UInt t = x % y;
>             x = y;
>             y = t;
>         }
>         return x;
>     }

>     template <class Int>
>     inline
>     typename std::enable_if
>     <
>         std::is_unsigned<Int>::value,
>         void
>     >::type
>     check_non_negative(Int d1, Int d2)
>     {
>     }

>     template <class Int>
>     typename std::enable_if
>     <
>         !std::is_unsigned<Int>::value,
>         void
>     >::type
>     check_non_negative(Int d1, Int d2)
>     {
>         if (d1 < Int(0) || d2 < Int(0))
>             throw std::invalid_argument("expected non-negative argument");
>     }

>     template <class UInt>
>     UInt
>     count_each_combination(UInt d1, UInt d2)
>     {
>         check_non_negative(d1, d2);
>         if (d2 < d1)
>             std::swap(d1, d2);
>         if (d1 == UInt())
>             return 1;
>         if (d1 > std::numeric_limits<UInt>::max() - d2)
>             throw std::overflow_error("overflow in count_each_combination");
>         UInt n = d1 + d2;
>         UInt r = n;
>         --n;
>         for (UInt k = UInt(2); k <= d1; ++k, --n)
>         {
>             // r = r * n / k, known to not not have truncation error
>             UInt g = gcd(r, k);
>             r /= g;
>             UInt t = n / (k / g);
>             if (r > std::numeric_limits<UInt>::max() / t)
>                 throw std::overflow_error("overflow in count_each_combination");
>             r *= t;
>         }
>         return r;
>     }

>     template <class BidirIter>
>     std::uintmax_t
>     count_each_combination(BidirIter first, BidirIter mid, BidirIter last)
>     {
>         return count_each_combination<std::uintmax_t>
>                               (std::distance(first, mid), std::distance(mid, last));
>     }

>     // For each of the permutation algorithms, use for_each_combination (or
>     //    combine_discontinuous) to handle the "r out of N" part of the algorithm.
>     //    Thus each permutation algorithm has to deal only with an "N out of N"
>     //    problem.  I.e. For each combination of r out of N items, permute it thusly.
>     template <class BidirIter, class Function>
>     Function
>     for_each_permutation(BidirIter first, BidirIter mid,
>                          BidirIter last, Function f)
>     {
>         typedef typename std::iterator_traits<BidirIter>::difference_type D;
>         typedef detail::bound_range<Function&, BidirIter> Wf;
>         typedef detail::call_permute<Wf, BidirIter> PF;
>         Wf wfunc(f, first, mid);
>         D d1 = std::distance(first, mid);
>         PF pf(wfunc, first, mid, d1);
>         detail::combine_discontinuous(first, mid, d1,
>                                       mid, last, std::distance(mid, last),
>                                       pf);
>         return f;
>     }

>     template <class UInt>
>     UInt
>     count_each_permutation(UInt d1, UInt d2)
>     {
>         // return (d1+d2)!/d2!
>         check_non_negative(d1, d2);
>         if (d1 > std::numeric_limits<UInt>::max() - d2)
>             throw std::overflow_error("overflow in count_each_permutation");
>         UInt n = d1 + d2;
>         UInt r(1);
>         for (; n > d2; --n)
>         {
>             if (r > std::numeric_limits<UInt>::max() / n)
>                 throw std::overflow_error("overflow in count_each_permutation");
>             r *= n;
>         }
>         return r;
>     }

>     template <class BidirIter>
>     std::uintmax_t
>     count_each_permutation(BidirIter first, BidirIter mid, BidirIter last)
>     {
>         return count_each_permutation<std::uintmax_t>
>                               (std::distance(first, mid), std::distance(mid, last));
>     }

>     namespace detail
>     {

>     // Adapt functor to permute over [first+1, last)
>     //   A circular permutation of N items is done by holding the first item and
>     //   permuting [first+1, last).
>     template <class Function, class BidirIter>
>     class circular_permutation
>     {
>         typedef typename std::iterator_traits<BidirIter>::difference_type D;

>         Function f_;
>         D s_;

>     public:
>         explicit circular_permutation(Function f, D s) : f_(f), s_(s) {}

>         bool
>         operator()(BidirIter first, BidirIter last)
>         {
>             if (s_ <= 1)
>                 return f_(first, last);
>             bound_range<Function, BidirIter> f(f_, first, last);
>             return permute(std::next(first), last, s_ - 1, f);
>         }
>     };

>     }  // detail

>     template <class BidirIter, class Function>
>     Function
>     for_each_circular_permutation(BidirIter first,
>                                   BidirIter mid,
>                                   BidirIter last, Function f)
>     {
>         for_each_combination(first, mid, last, detail::circular_permutation<Function&,
>                               BidirIter>(f, std::distance(first, mid)));
>         return f;
>     }

>     template <class UInt>
>     UInt
>     count_each_circular_permutation(UInt d1, UInt d2)
>     {
>         // return d1 > 0 ? (d1+d2)!/(d1*d2!) : 1
>         check_non_negative(d1, d2);
>         if (d1 == UInt())
>             return 1;
>         UInt r;
>         if (d1 <= d2)
>         {
>             try
>             {
>                 r = count_each_combination(d1, d2);
>             }
>             catch (const std::overflow_error&)
>             {
>                 throw std::overflow_error("overflow in count_each_circular_permutation");
>             }
>             for (--d1; d1 > UInt(1); --d1)
>             {
>                 if (r > std::numeric_limits<UInt>::max()/d1)
>                     throw std::overflow_error("overflow in count_each_circular_permutation");
>                 r *= d1;
>             }
>         }
>         else
>         {   // functionally equivalent but faster algorithm
>             if (d1 > std::numeric_limits<UInt>::max() - d2)
>                 throw std::overflow_error("overflow in count_each_circular_permutation");
>             UInt n = d1 + d2;
>             r = 1;
>             for (; n > d1; --n)
>             {
>                 if (r > std::numeric_limits<UInt>::max()/n)
>                     throw std::overflow_error("overflow in count_each_circular_permutation");
>                 r *= n;
>             }
>             for (--n; n > d2; --n)
>             {
>                 if (r > std::numeric_limits<UInt>::max()/n)
>                     throw std::overflow_error("overflow in count_each_circular_permutation");
>                 r *= n;
>             }
>         }
>         return r;
>     }

>     template <class BidirIter>
>     std::uintmax_t
>     count_each_circular_permutation(BidirIter first, BidirIter mid, BidirIter last)
>     {
>         return count_each_circular_permutation<std::uintmax_t>
>                               (std::distance(first, mid), std::distance(mid, last));
>     }

>     namespace detail
>     {

>     // Difficult!!!  See notes for operator().
>     template <class Function, class Size>
>     class reversible_permutation
>     {
>         Function f_;
>         Size s_;

>     public:
>         reversible_permutation(Function f, Size s) : f_(f), s_(s) {}

>         template <class BidirIter>
>         bool
>         operator()(BidirIter first, BidirIter last);
>     };

>     // rev1 looks like call_permute
>     template <class Function, class BidirIter>
>     class rev1
>     {
>         typedef typename std::iterator_traits<BidirIter>::difference_type D;

>         Function f_;
>         BidirIter first1_;
>         BidirIter last1_;
>         D d1_;

>     public:
>         rev1(Function f, BidirIter first, BidirIter last, D d)
>             : f_(f), first1_(first), last1_(last), d1_(d) {}

>         bool operator()()
>         {
>             return permute(first1_, last1_, d1_, f_);
>         }
>     };

>     // For each permutation in [first1, last1),
>     //     call f() for each permutation of [first2, last2).
>     template <class Function, class BidirIter>
>     class rev2
>     {
>         typedef typename std::iterator_traits<BidirIter>::difference_type D;

>         Function f_;
>         BidirIter first1_;
>         BidirIter last1_;
>         D d1_;
>         BidirIter first2_;
>         BidirIter last2_;
>         D d2_;

>     public:
>         rev2(Function f, BidirIter first1, BidirIter last1, D d1,
>                          BidirIter first2, BidirIter last2, D d2)
>             : f_(f), first1_(first1), last1_(last1), d1_(d1),
>                      first2_(first2), last2_(last2), d2_(d2) {}

>         bool operator()()
>         {
>             call_permute<Function, BidirIter> f(f_, first2_, last2_, d2_);
>             return permute(first1_, last1_, d1_, f);
>         }
>     };

>     // For each permutation in [first1, last1),
>     //     and for each permutation of [first2, last2)
>     //     call f() for each permutation of [first3, last3).
>     template <class Function, class BidirIter>
>     class rev3
>     {
>         typedef typename std::iterator_traits<BidirIter>::difference_type D;

>         Function f_;
>         BidirIter first1_;
>         BidirIter last1_;
>         D d1_;
>         BidirIter first2_;
>         BidirIter last2_;
>         D d2_;
>         BidirIter first3_;
>         BidirIter last3_;
>         D d3_;

>     public:
>         rev3(Function f, BidirIter first1, BidirIter last1, D d1,
>                          BidirIter first2, BidirIter last2, D d2,
>                          BidirIter first3, BidirIter last3, D d3)
>             : f_(f), first1_(first1), last1_(last1), d1_(d1),
>                      first2_(first2), last2_(last2), d2_(d2),
>                      first3_(first3), last3_(last3), d3_(d3) {}

>         bool operator()()
>         {
>             rev2<Function, BidirIter> f(f_, first2_, last2_, d2_, first3_, last3_, d3_);
>             return permute(first1_, last1_, d1_, f);
>         }
>     };

>     // There are simpler implementations.  I believe the simpler ones are far more
>     //     expensive.
>     template <class Function, class Size>
>     template <class BidirIter>
>     bool
>     reversible_permutation<Function, Size>::operator()(BidirIter first,
>                                                        BidirIter last)
>     {
>         typedef typename std::iterator_traits<BidirIter>::difference_type difference_type;
>         typedef rev2<bound_range<Function&, BidirIter>, BidirIter> F2;
>         typedef rev3<bound_range<Function&, BidirIter>, BidirIter> F3;
>         // When the range is 0 - 2, then this is just a combination of N out of N
>         //   elements.
>         if (s_ < 3)
>             return f_(first, last);
>         using std::swap;
>         // Hold the first element steady and call f_(first, last) for each
>         //    permutation in [first+1, last).
>         BidirIter a = std::next(first);
>         bound_range<Function&, BidirIter> f(f_, first, last);
>         if (permute(a, last, s_-1, f))
>             return true;
>         // Beginning with the first element, swap the previous element with the
>         //    next element.  For each swap, call f_(first, last) for each
>         //    permutation of the discontinuous range:
>         //    [prior to the orignal element] + [after the original element].
>         Size s2 = s_ / 2;
>         BidirIter am1 = first;
>         BidirIter ap1 = std::next(a);
>         for (Size i = 1; i < s2; ++i, ++am1, ++a, ++ap1)
>         {
>             swap(*am1, *a);
>             F2 f2(f, first, a, i, ap1, last, s_ - i - 1);
>             if (combine_discontinuous(first, a, i, ap1, last, s_ - i - 1, f2))
>                 return true;
>         }
>         // If [first, last) has an even number of elements, then fix it up to the
>         //     original permutation.
>         if (2 * s2 == s_)
>         {
>             std::rotate(first, am1, a);
>         }
>         // else if the range has length 3, we need one more call and the fix is easy.
>         else if (s_ == 3)
>         {
>             swap(*am1, *a);
>             if (f_(first, last))
>                 return true;
>             swap(*am1, *a);
>         }
>         // else the range is an odd number greater than 3.  We need to permute
>         //     through exactly half of the permuations with the original element in
>         //     the middle.
>         else
>         {
>             // swap the original first element into the middle, and hold the current
>             //   first element steady.  This creates a discontinuous range:
>             //     [first+1, middle) + [middle+1, last).  Run through all permutations
>             //     of that discontinuous range.
>             swap(*am1, *a);
>             BidirIter b = first;
>             BidirIter bp1 = std::next(b);
>             F2 f2(f, bp1, a, s2-1, ap1, last, s_ - s2 - 1);
>             if (combine_discontinuous(bp1, a, s2-1, ap1, last, s_ - s2 - 1, f2))
>                 return true;
>             // Swap the current first element into every place from first+1 to middle-1.
>             //   For each location, hold it steady to create the following discontinuous
>             //   range (made of 3 ranges): [first, b-1) + [b+1, middle) + [middle+1, last).
>             //   For each b in [first+1, middle-1), run through all permutations of
>             //      the discontinuous ranges.
>             b = bp1;
>             ++bp1;
>             BidirIter bm1 = first;
>             for (Size i = 1; i < s2-1; ++i, ++bm1, ++b, ++bp1)
>             {
>                 swap(*bm1, *b);
>                 F3 f3(f, first, b, i, bp1, a, s2-i-1, ap1, last, s_ - s2 - 1);
>                 if (combine_discontinuous3(first, b, i, bp1, a, s2-i-1, ap1, last, s_-s2-1, f3))
>                     return true;
>             }
>             // swap b into into middle-1, creates a discontinuous range:
>             //     [first, middle-1) + [middle+1, last).  Run through all permutations
>             //     of that discontinuous range.
>             swap(*bm1, *b);
>             F2 f21(f, first, b, s2-1, ap1, last, s_ - s2 - 1);
>             if (combine_discontinuous(first, b, s2-1, ap1, last, s_ - s2 - 1, f21))
>                 return true;
>             // Revert [first, last) to original order
>             std::reverse(first, b);
>             std::reverse(first, ap1);
>         }
>         return false;
>     }

>     }  // detail

>     template <class BidirIter, class Function>
>     Function
>     for_each_reversible_permutation(BidirIter first,
>                                     BidirIter mid,
>                                     BidirIter last, Function f)
>     {
>         typedef typename std::iterator_traits<BidirIter>::difference_type D;
>         for_each_combination(first, mid, last,
>                       detail::reversible_permutation<Function&, D>(f,
>                                                   std::distance(first, mid)));
>         return f;
>     }

>     template <class UInt>
>     UInt
>     count_each_reversible_permutation(UInt d1, UInt d2)
>     {
>         // return d1 > 1 ? (d1+d2)!/(2*d2!) : (d1+d2)!/d2!
>         check_non_negative(d1, d2);
>         if (d1 > std::numeric_limits<UInt>::max() - d2)
>             throw std::overflow_error("overflow in count_each_reversible_permutation");
>         UInt n = d1 + d2;
>         UInt r(1);
>         if (d1 > UInt(1))
>         {
>             r = n;
>             if ((n & UInt(1)) == UInt(0))
>                 r /= UInt(2);
>             --n;
>             UInt t = n;
>             if ((t & UInt(1)) == UInt(0))
>                 t /= UInt(2);
>             if (r > std::numeric_limits<UInt>::max() / t)
>                 throw std::overflow_error("overflow in count_each_reversible_permutation");
>             r *= t;
>             --n;
>         }
>         for (; n > d2; --n)
>         {
>             if (r > std::numeric_limits<UInt>::max() / n)
>                 throw std::overflow_error("overflow in count_each_reversible_permutation");
>             r *= n;
>         }
>         return r;
>     }

>     template <class BidirIter>
>     std::uintmax_t
>     count_each_reversible_permutation(BidirIter first, BidirIter mid, BidirIter last)
>     {
>         return count_each_reversible_permutation<std::uintmax_t>
>                               (std::distance(first, mid), std::distance(mid, last));
>     }

>     namespace detail
>     {

>     // Adapt functor to permute over [first+1, last)
>     //   A reversible circular permutation of N items is done by holding the first
>     //   item and reverse-permuting [first+1, last).
>     template <class Function, class BidirIter>
>     class reverse_circular_permutation
>     {
>         typedef typename std::iterator_traits<BidirIter>::difference_type D;

>         Function f_;
>         D s_;

>     public:
>         explicit reverse_circular_permutation(Function f, D s) : f_(f), s_(s) {}

>         bool
>         operator()(BidirIter first, BidirIter last)
>         {
>             if (s_ == 1)
>                 return f_(first, last);
>             typedef typename std::iterator_traits<BidirIter>::difference_type D;
>             typedef bound_range<Function, BidirIter> BoundFunc;
>             BoundFunc f(f_, first, last);
>             BidirIter n = std::next(first);
>             return reversible_permutation<BoundFunc, D>(f, std::distance(n, last))(n, last);
>         }
>     };

>     }  // detail

>     template <class BidirIter, class Function>
>     Function
>     for_each_reversible_circular_permutation(BidirIter first,
>                                              BidirIter mid,
>                                              BidirIter last, Function f)
>     {
>         for_each_combination(first, mid, last, detail::reverse_circular_permutation<Function&,
>                               BidirIter>(f, std::distance(first, mid)));
>         return f;
>     }

>     template <class UInt>
>     UInt
>     count_each_reversible_circular_permutation(UInt d1, UInt d2)
>     {
>         // return d1 == 0 ? 1 : d1 <= 2 ? (d1+d2)!/(d1*d2!) : (d1+d2)!/(2*d1*d2!)
>         check_non_negative(d1, d2);
>         UInt r;
>         try
>         {
>             r = count_each_combination(d1, d2);
>         }
>         catch (const std::overflow_error&)
>         {
>             throw std::overflow_error("overflow in count_each_reversible_circular_permutation");
>         }
>         if (d1 > UInt(3))
>         {
>             for (--d1; d1 > UInt(2); --d1)
>             {
>                 if (r > std::numeric_limits<UInt>::max()/d1)
>                     throw std::overflow_error("overflow in count_each_reversible_circular_permutation");
>                 r *= d1;
>             }
>         }
>         return r;
>     }

>     template <class BidirIter>
>     std::uintmax_t
>     count_each_reversible_circular_permutation(BidirIter first, BidirIter mid,
>                                                    BidirIter last)
>     {
>         return count_each_reversible_circular_permutation<std::uintmax_t>
>                               (std::distance(first, mid), std::distance(mid, last));
>     }