Ticket #6250: make_index.cc

File make_index.cc, 3.8 KB (added by ne01026@…, 11 years ago)

an implementation of make_index using shufflebase indexes an arbitrary transformed range

Line 
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
12namespace meta
13{
14 /* Calculates the base iterator (fallback) */
15template < class P_I, class P_E = void >
16 struct base_iterator { typedef P_I type; };
17
18 /* Calculates the base iterator */
19template < class P_I >
20 struct base_iterator_force
21 {
22typedef P_I adapted;
23 typedef
24 typename base_iterator < typename adapted ::base_type > ::type type; };
25
26 /* Calculates the base iterator, if applicable */
27template < class P_I >
28 struct base_iterator
29 <
30P_I,
31typename
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 */
36template < class P_C >
37struct make_index
38{ typedef P_C container;
39typedef
40::std ::vector
41<
42::boost ::reference_wrapper
43 <
44typename
45::std ::iterator_traits
46 <
47typename
48base_iterator < typename ::boost :: range_iterator < container > ::type >
49::type > ::value_type const > >
50result; }; }
51#endif /* &meta */
52
53template < class P_C >
54/* Creates an ordered index of a transformed range as a vector of references */
55typename meta ::make_index < P_C > ::result make_index (P_C const &p_c)
56{
57 typedef P_C container;
58typedef 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 */
68template < class P_N = unsigned char >
69struct 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
76template < class P_V, class P_C, class P_T >
77static 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
81int 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;
86typedef 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 */
89mycont 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