| 1 | #include <iostream>
|
|---|
| 2 | #include <vector>
|
|---|
| 3 | #include <boost/range/algorithm/transform.hpp>
|
|---|
| 4 | #include <boost/range/algorithm/copy.hpp>
|
|---|
| 5 | #include <boost/range/algorithm/sort.hpp>
|
|---|
| 6 | #include <boost/range/adaptor/transformed.hpp>
|
|---|
| 7 | #include <boost/array.hpp>
|
|---|
| 8 | #include <boost/ref.hpp>
|
|---|
| 9 | #include <boost/bind.hpp>
|
|---|
| 10 |
|
|---|
| 11 | #if 1
|
|---|
| 12 | namespace meta
|
|---|
| 13 | {
|
|---|
| 14 | /* Calculates the base iterator (fallback) */
|
|---|
| 15 | template < class P_I, class P_E = void >
|
|---|
| 16 | struct base_iterator { typedef P_I type; };
|
|---|
| 17 |
|
|---|
| 18 | /* Calculates the base iterator */
|
|---|
| 19 | template < class P_I >
|
|---|
| 20 | struct base_iterator_force
|
|---|
| 21 | {
|
|---|
| 22 | typedef P_I adapted;
|
|---|
| 23 | typedef
|
|---|
| 24 | typename base_iterator < typename adapted ::base_type > ::type type; };
|
|---|
| 25 |
|
|---|
| 26 | /* Calculates the base iterator, if applicable */
|
|---|
| 27 | template < class P_I >
|
|---|
| 28 | struct base_iterator
|
|---|
| 29 | <
|
|---|
| 30 | P_I,
|
|---|
| 31 | typename
|
|---|
| 32 | ::boost ::enable_if_c < sizeof (typename P_I:: base_type) || 01>:: type >
|
|---|
| 33 | :public base_iterator_force < P_I > { };
|
|---|
| 34 |
|
|---|
| 35 | /* Calculates the result of make_index */
|
|---|
| 36 | template < class P_C >
|
|---|
| 37 | struct make_index
|
|---|
| 38 | { typedef P_C container;
|
|---|
| 39 | typedef
|
|---|
| 40 | ::std ::vector
|
|---|
| 41 | <
|
|---|
| 42 | ::boost ::reference_wrapper
|
|---|
| 43 | <
|
|---|
| 44 | typename
|
|---|
| 45 | ::std ::iterator_traits
|
|---|
| 46 | <
|
|---|
| 47 | typename
|
|---|
| 48 | base_iterator < typename ::boost :: range_iterator < container > ::type >
|
|---|
| 49 | ::type > ::value_type const > >
|
|---|
| 50 | result; }; }
|
|---|
| 51 | #endif /* &meta */
|
|---|
| 52 |
|
|---|
| 53 | template < class P_C >
|
|---|
| 54 | /* Creates an ordered index of a transformed range as a vector of references */
|
|---|
| 55 | typename meta ::make_index < P_C > ::result make_index (P_C const &p_c)
|
|---|
| 56 | {
|
|---|
| 57 | typedef P_C container;
|
|---|
| 58 | typedef typename meta ::make_index < container > ::result result;
|
|---|
| 59 | result l_r
|
|---|
| 60 | ((::boost ::copy_range < result > (p_c | ::boost ::adaptors ::unwrapped)));
|
|---|
| 61 | ::boost ::sort (l_r |
|
|---|
| 62 | ::boost ::adaptors ::transformed
|
|---|
| 63 | (::boost ::begin (p_c) .functor ())
|
|---|
| 64 | | ::boost ::adaptors ::shufflebase);
|
|---|
| 65 | return l_r; }
|
|---|
| 66 |
|
|---|
| 67 | /* a test structure with only one aspect */
|
|---|
| 68 | template < class P_N = unsigned char >
|
|---|
| 69 | struct underlying
|
|---|
| 70 | { typedef P_N number;
|
|---|
| 71 | number m_;
|
|---|
| 72 | /* accessors, mandatory per C++ paradigm, support mem_fun */
|
|---|
| 73 | number &m () { return m_; }
|
|---|
| 74 | /* convenient << */ number const &m () const { return m_; }};
|
|---|
| 75 |
|
|---|
| 76 | template < class P_V, class P_C, class P_T >
|
|---|
| 77 | static inline ::std ::basic_ostream < P_C, P_T >
|
|---|
| 78 | &operator <<
|
|---|
| 79 | (class ::std ::basic_ostream < P_C, P_T > &p_s, struct underlying < P_V > const &p_u) { return p_s << +p_u .m_; }
|
|---|
| 80 |
|
|---|
| 81 | int main (int, char *[])
|
|---|
| 82 | {
|
|---|
| 83 | enum LocalParam { BASE = 073, VALUE = 030 };
|
|---|
| 84 | /* Create a shuffled array */ typedef struct underlying < > u;
|
|---|
| 85 | typedef struct ::boost ::array < u, +BASE - 01 > mycont;
|
|---|
| 86 | typedef typename meta ::make_index < mycont > ::result result;
|
|---|
| 87 | static char const l_delim [] = ".\n", l_sep [] = " ";
|
|---|
| 88 | /* u [0] = VALUE; u [n + 1] = u [n] * VALUE % BASE */
|
|---|
| 89 | mycont v = {{{ +VALUE }}};
|
|---|
| 90 | ::boost ::transform
|
|---|
| 91 | (::boost ::make_iterator_range (v, 0, 01)
|
|---|
| 92 | |
|
|---|
| 93 | ::boost ::adaptors ::transformed (::std ::mem_fun_ref < u ::number const & > (&u ::m)),
|
|---|
| 94 | ::boost ::make_transform_iterator (::boost ::begin (v) + 01, ::std ::mem_fun_ref < u ::number & > (&u ::m)),
|
|---|
| 95 | ::boost ::bind
|
|---|
| 96 | (::std ::modulus < unsigned > (), ::boost ::bind (::std ::multiplies < unsigned > (), +VALUE, _1), +BASE));
|
|---|
| 97 | /* Print the array */
|
|---|
| 98 | ::std ::cout << separated (v, l_sep) << l_delim;
|
|---|
| 99 | {
|
|---|
| 100 | /* Index the array */
|
|---|
| 101 | result const
|
|---|
| 102 | ndx
|
|---|
| 103 | ((make_index
|
|---|
| 104 | (v
|
|---|
| 105 | |
|
|---|
| 106 | ::boost ::adaptors ::transformed
|
|---|
| 107 | (::std ::mem_fun_ref < u ::number const & > (&u ::m)))));
|
|---|
| 108 | /* print the resulting permutation */
|
|---|
| 109 | ::std ::cout
|
|---|
| 110 | <<
|
|---|
| 111 | separated
|
|---|
| 112 | (::boost ::make_iterator_range (ndx)
|
|---|
| 113 | |
|
|---|
| 114 | ::boost ::adaptors ::transformed
|
|---|
| 115 | (
|
|---|
| 116 | ::boost:: bind
|
|---|
| 117 | (::std ::distance < ::boost ::range_iterator < mycont const > ::type >, ::boost ::const_begin (v),
|
|---|
| 118 | ::boost ::bind (&::boost ::range_value < result > ::type ::get_pointer, _1))), l_sep) << l_delim; }
|
|---|
| 119 | return ::std ::cout .flush ()? +EXIT_SUCCESS: +EXIT_FAILURE; }
|
|---|
| 120 |
|
|---|