1 /* Boost.MultiIndex example of use of multi_index_container::ctor_args_list.
2 *
3 * Copyright 2003-2008 Joaquin M Lopez Munoz.
4 * Distributed under the Boost Software License, Version 1.0.
5 * (See accompanying file LICENSE_1_0.txt or copy at
6 * http://www.boost.org/LICENSE_1_0.txt)
7 *
8 * See http://www.boost.org/libs/multi_index for library home page.
9 */
10
11 #if !defined(NDEBUG)
12 #define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
13 #define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
14 #endif
15
16 #include <boost/multi_index_container.hpp>
17 #include <boost/multi_index/identity.hpp>
18 #include <boost/multi_index/ordered_index.hpp>
19 #include <algorithm>
20 #include <iostream>
21 #include <iterator>
22
23 using boost::multi_index_container;
24 using namespace boost::multi_index;
25
26 /* modulo_less order numbers according to their division residual.
27 * For instance, if modulo==10 then 22 is less than 15 as 22%10==2 and
28 * 15%10==5.
29 */
30
31 template<typename IntegralType>
32 struct modulo_less
33 {
modulo_lessmodulo_less34 modulo_less(IntegralType m):modulo(m){}
35
operator ()modulo_less36 bool operator()(IntegralType x,IntegralType y)const
37 {
38 return (x%modulo)<(y%modulo);
39 }
40
41 private:
42 IntegralType modulo;
43 };
44
45 /* multi_index_container of unsigned ints holding a "natural" index plus
46 * an ordering based on modulo_less.
47 */
48
49 typedef multi_index_container<
50 unsigned int,
51 indexed_by<
52 ordered_unique<identity<unsigned int> >,
53 ordered_non_unique<identity<unsigned int>, modulo_less<unsigned int> >
54 >
55 > modulo_indexed_set;
56
main()57 int main()
58 {
59 /* define a modulo_indexed_set with modulo==10 */
60
61 modulo_indexed_set::ctor_args_list args_list=
62 boost::make_tuple(
63 /* ctor_args for index #0 is default constructible */
64 nth_index<modulo_indexed_set,0>::type::ctor_args(),
65
66 /* first parm is key_from_value, second is our sought for key_compare */
67 boost::make_tuple(identity<unsigned int>(),modulo_less<unsigned int>(10))
68 );
69
70 modulo_indexed_set m(args_list);
71 /* this could have be written online without the args_list variable,
72 * left as it is for explanatory purposes. */
73
74 /* insert some numbers */
75
76 unsigned int numbers[]={0,1,20,40,33,68,11,101,60,34,88,230,21,4,7,17};
77 const std::size_t numbers_length(sizeof(numbers)/sizeof(numbers[0]));
78
79 m.insert(&numbers[0],&numbers[numbers_length]);
80
81 /* lists all numbers in order, along with their "equivalence class", that is,
82 * the equivalent numbers under modulo_less
83 */
84
85 for(modulo_indexed_set::iterator it=m.begin();it!=m.end();++it){
86 std::cout<<*it<<" -> ( ";
87
88 nth_index<modulo_indexed_set,1>::type::iterator it0,it1;
89 boost::tie(it0,it1)=get<1>(m).equal_range(*it);
90 std::copy(it0,it1,std::ostream_iterator<unsigned int>(std::cout," "));
91
92 std::cout<<")"<<std::endl;
93 }
94
95 return 0;
96 }
97