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