1 /* Boost.MultiIndex example of use of random access indices.
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 <boost/multi_index/random_access_index.hpp>
20 #include <boost/tokenizer.hpp>
21 #include <algorithm>
22 #include <iostream>
23 #include <iterator>
24 #include <string>
25
26 using boost::multi_index_container;
27 using namespace boost::multi_index;
28
29 /* text_container holds words as inserted and also keep them indexed
30 * by dictionary order.
31 */
32
33 typedef multi_index_container<
34 std::string,
35 indexed_by<
36 random_access<>,
37 ordered_non_unique<identity<std::string> >
38 >
39 > text_container;
40
41 /* ordered index */
42
43 typedef nth_index<text_container,1>::type ordered_text;
44
45 /* Helper function for obtaining the position of an element in the
46 * container.
47 */
48
49 template<typename IndexIterator>
text_position(const text_container & tc,IndexIterator it)50 text_container::size_type text_position(
51 const text_container& tc,IndexIterator it)
52 {
53 /* project to the base index and calculate offset from begin() */
54
55 return project<0>(tc,it)-tc.begin();
56 }
57
58 typedef boost::tokenizer<boost::char_separator<char> > text_tokenizer;
59
main()60 int main()
61 {
62 std::string text=
63 "'Oh, you wicked little thing!' cried Alice, catching up the kitten, "
64 "and giving it a little kiss to make it understand that it was in "
65 "disgrace. 'Really, Dinah ought to have taught you better manners! You "
66 "ought, Dinah, you know you ought!' she added, looking reproachfully at "
67 "the old cat, and speaking in as cross a voice as she could manage "
68 "-- and then she scrambled back into the armchair, taking the kitten and "
69 "the worsted with her, and began winding up the ball again. But she "
70 "didn't get on very fast, as she was talking all the time, sometimes to "
71 "the kitten, and sometimes to herself. Kitty sat very demurely on her "
72 "knee, pretending to watch the progress of the winding, and now and then "
73 "putting out one paw and gently touching the ball, as if it would be glad "
74 "to help, if it might.";
75
76 /* feed the text into the container */
77
78 text_container tc;
79 tc.reserve(text.size()); /* makes insertion faster */
80 text_tokenizer tok(text,boost::char_separator<char>(" \t\n.,;:!?'\"-"));
81 std::copy(tok.begin(),tok.end(),std::back_inserter(tc));
82
83 std::cout<<"enter a position (0-"<<tc.size()-1<<"):";
84 text_container::size_type pos=tc.size();
85 std::cin>>pos;
86 if(pos>=tc.size()){
87 std::cout<<"out of bounds"<<std::endl;
88 }
89 else{
90 std::cout<<"the word \""<<tc[pos]<<"\" appears at position(s): ";
91
92 std::pair<ordered_text::iterator,ordered_text::iterator> p=
93 get<1>(tc).equal_range(tc[pos]);
94 while(p.first!=p.second){
95 std::cout<<text_position(tc,p.first++)<<" ";
96 }
97
98 std::cout<<std::endl;
99 }
100
101 return 0;
102 }
103