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 |
|
---|