// (by Ariel Badichi) #include <boost/static_assert.hpp> #include <boost/mpl/vector_c.hpp> #include <boost/mpl/equal_to.hpp> #include <boost/mpl/if.hpp> #include <boost/mpl/iterator_tags.hpp> #include <boost/mpl/iterator_category.hpp> #include <boost/mpl/advance.hpp> #include <boost/mpl/pop_front.hpp> #include <boost/mpl/front.hpp> #include <boost/mpl/next.hpp> #include <boost/mpl/prior.hpp> #include <boost/mpl/deref.hpp> #include <boost/mpl/begin.hpp> #include <boost/mpl/bool.hpp> #include <boost/mpl/and.hpp> #include <boost/mpl/size_t.hpp> #include <boost/mpl/at.hpp> #include <boost/mpl/list_c.hpp>
namespace mpl = boost::mpl;
template<typename Iter, typename OrderIter?> struct permutation_iterator { typedef typename mpl::iterator_category<OrderIter?>::type category;
typedef typename mpl::advance< Iter, typename mpl::deref<OrderIter?>::type >::type base;
typedef typename mpl::deref<base>::type type; };
namespace boost { namespace mpl { template<typename Iter, typename OrderIter?> struct next<permutation_iterator<Iter, OrderIter?> > { typedef permutation_iterator< Iter, typename mpl::next<OrderIter?>::type > type; };
template<typename Iter, typename OrderIter?> struct prior<permutation_iterator<Iter, OrderIter?> > { typedef permutation_iterator< Iter, typename mpl::prior<OrderIter?>::type > type; }; } }
template<typename Iter1, typename Iter2, int N> struct compare : mpl::and_< mpl::equal_to< typename mpl::deref<Iter1>::type, typename mpl::deref<Iter2>::type >, compare< typename mpl::next<Iter1>::type, typename mpl::next<Iter2>::type, N - 1 > > {};
template<typename Iter1, typename Iter2> struct compare<Iter1, Iter2, 0> : mpl::true_ {};
int main() { typedef mpl::vector_c<int, 0, 1, 2, 3, 4> v; typedef mpl::list_c<int, 3, 1, 4, 0, 2> order; typedef mpl::begin<v>::type first; typedef permutation_iterator<first, mpl::begin<order>::type> p; BOOST_STATIC_ASSERT((compare<p, mpl::begin<order>::type, 5>::value));
typedef mpl::advance_c<p, 3>::type q; BOOST_STATIC_ASSERT((mpl::deref<q>::type::value == 0));
/* // only valid when bidirectional order sequence is used typedef mpl::prior<q>::type r; BOOST_STATIC_ASSERT((mpl::deref<r>::type::value == 4)); */ }