1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
/* Boost.MultiIndex example of serialization of a MRU list.
*
* Copyright 2003-2005 Joaqun M Lpez Muoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#if !defined(NDEBUG)
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
using namespace boost::multi_index;
/* An MRU (most recently used) list keeps record of the last n
* inserted items, listing first the newer ones. Care has to be
* taken when a duplicate item is inserted: instead of letting it
* appear twice, the MRU list relocates it to the first position.
*/
template <typename Item>
class mru_list
{
typedef multi_index_container<
Item,
indexed_by<
sequenced<>,
hashed_unique<identity<Item> >
>
> item_list;
public:
typedef Item item_type;
typedef typename item_list::iterator iterator;
mru_list(std::size_t max_num_items):max_num_items(max_num_items){}
void insert(const item_type& item)
{
std::pair<iterator,bool> p=il.push_front(item);
if(!p.second){ /* duplicate item */
il.relocate(il.begin(),p.first); /* put in front */
}
else if(il.size()>max_num_items){ /* keep the length <= max_num_items */
il.pop_back();
}
}
iterator begin(){return il.begin();}
iterator end(){return il.end();}
/* Utilities to save and load the MRU list, internally
* based on Boost.Serialization.
*/
void save_to_file(const char* file_name)const
{
std::ofstream ofs(file_name);
boost::archive::text_oarchive oa(ofs);
oa<<boost::serialization::make_nvp("mru",*this);
}
void load_from_file(const char* file_name)
{
std::ifstream ifs(file_name);
if(ifs){
boost::archive::text_iarchive ia(ifs);
ia>>boost::serialization::make_nvp("mru",*this);
}
}
private:
item_list il;
std::size_t max_num_items;
/* serialization support */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar,const unsigned int)
{
ar&BOOST_SERIALIZATION_NVP(il);
ar&BOOST_SERIALIZATION_NVP(max_num_items);
}
};
int main()
{
const char* mru_store="mru_store";
/* Construct a MRU limited to 10 items and retrieve its
* previous contents.
*/
mru_list<std::string> mru(10);
mru.load_from_file(mru_store);
/* main loop */
for(;;){
std::cout<<"enter a term: ";
std::string line;
std::getline(std::cin,line);
if(line.empty())break;
std::string term;
std::istringstream iss(line);
iss>>term;
if(term.empty())break;
mru.insert(term);
std::cout<<"most recently entered terms:"<<std::endl;
std::copy(
mru.begin(),mru.end(),
std::ostream_iterator<std::string>(std::cout,"\n"));
}
/* persist the MRU list */
mru.save_to_file(mru_store);
return 0;
}
|