#include #include #include #include #include #include #include #include #include #if 1 namespace meta { /* Calculates the base iterator (fallback) */ template < class P_I, class P_E = void > struct base_iterator { typedef P_I type; }; /* Calculates the base iterator */ template < class P_I > struct base_iterator_force { typedef P_I adapted; typedef typename base_iterator < typename adapted ::base_type > ::type type; }; /* Calculates the base iterator, if applicable */ template < class P_I > struct base_iterator < P_I, typename ::boost ::enable_if_c < sizeof (typename P_I:: base_type) || 01>:: type > :public base_iterator_force < P_I > { }; /* Calculates the result of make_index */ template < class P_C > struct make_index { typedef P_C container; typedef ::std ::vector < ::boost ::reference_wrapper < typename ::std ::iterator_traits < typename base_iterator < typename ::boost :: range_iterator < container > ::type > ::type > ::value_type const > > result; }; } #endif /* &meta */ template < class P_C > /* Creates an ordered index of a transformed range as a vector of references */ typename meta ::make_index < P_C > ::result make_index (P_C const &p_c) { typedef P_C container; typedef typename meta ::make_index < container > ::result result; result l_r ((::boost ::copy_range < result > (p_c | ::boost ::adaptors ::unwrapped))); ::boost ::sort (l_r | ::boost ::adaptors ::transformed (::boost ::begin (p_c) .functor ()) | ::boost ::adaptors ::shufflebase); return l_r; } /* a test structure with only one aspect */ template < class P_N = unsigned char > struct underlying { typedef P_N number; number m_; /* accessors, mandatory per C++ paradigm, support mem_fun */ number &m () { return m_; } /* convenient << */ number const &m () const { return m_; }}; template < class P_V, class P_C, class P_T > static inline ::std ::basic_ostream < P_C, P_T > &operator << (class ::std ::basic_ostream < P_C, P_T > &p_s, struct underlying < P_V > const &p_u) { return p_s << +p_u .m_; } int main (int, char *[]) { enum LocalParam { BASE = 073, VALUE = 030 }; /* Create a shuffled array */ typedef struct underlying < > u; typedef struct ::boost ::array < u, +BASE - 01 > mycont; typedef typename meta ::make_index < mycont > ::result result; static char const l_delim [] = ".\n", l_sep [] = " "; /* u [0] = VALUE; u [n + 1] = u [n] * VALUE % BASE */ mycont v = {{{ +VALUE }}}; ::boost ::transform (::boost ::make_iterator_range (v, 0, 01) | ::boost ::adaptors ::transformed (::std ::mem_fun_ref < u ::number const & > (&u ::m)), ::boost ::make_transform_iterator (::boost ::begin (v) + 01, ::std ::mem_fun_ref < u ::number & > (&u ::m)), ::boost ::bind (::std ::modulus < unsigned > (), ::boost ::bind (::std ::multiplies < unsigned > (), +VALUE, _1), +BASE)); /* Print the array */ ::std ::cout << separated (v, l_sep) << l_delim; { /* Index the array */ result const ndx ((make_index (v | ::boost ::adaptors ::transformed (::std ::mem_fun_ref < u ::number const & > (&u ::m))))); /* print the resulting permutation */ ::std ::cout << separated (::boost ::make_iterator_range (ndx) | ::boost ::adaptors ::transformed ( ::boost:: bind (::std ::distance < ::boost ::range_iterator < mycont const > ::type >, ::boost ::const_begin (v), ::boost ::bind (&::boost ::range_value < result > ::type ::get_pointer, _1))), l_sep) << l_delim; } return ::std ::cout .flush ()? +EXIT_SUCCESS: +EXIT_FAILURE; }