#include <string>
#include <ostream>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/tag.hpp>
#include <boost/lambda/lambda.hpp>
using namespace std;
using namespace boost::multi_index;
struct auth
{
string m_name;
string m_pass;
auth(const string &name, const string &pass)
: m_name(name), m_pass(pass) { }
bool operator<(const auth &o) const { return m_name < o.m_name; }
friend ostream &operator<<(ostream &os, const auth &a) { os << "(" << a.m_name << ", " << a.m_pass << ")"; return os; }
};
struct employee
{
int m_id;
auth m_auth;
int m_hire;
int m_resign;
employee(int id, const string &name, const string &pass, int hire, int resign)
: m_id(id), m_auth(name, pass), m_hire(hire), m_resign(resign) { }
bool operator<(const employee &o) const { return m_id < o.m_id; }
friend ostream &operator<<(ostream &os, const employee *e) { os << "(" << e->m_id << ", " << e->m_auth << ", " << e->m_hire << ", " << e->m_resign << ")"; return os; }
};
struct auth_t { };
struct change_resign {
int m_resign;
change_resign(int r) : m_resign(r) { }
void operator()(employee *e) { e->m_resign = m_resign; }
};
typedef multi_index_container<
employee *,
indexed_by<
/* sort by employee::operator< */
ordered_unique<identity<employee> >,
/* sort by less<int> on m_hire */
ordered_non_unique<member<employee, int, &employee::m_hire> >,
/* sort by less<auth> on m_auth */
ordered_non_unique<tag<auth_t>, member<employee, auth, &employee::m_auth> >
>
> employee_set;
int main()
{
employee_set es;
es.insert(new employee(1, "555", "555pass", 2012, 0));
es.insert(new employee(2, "444", "444pass", 2011, 0));
es.insert(new employee(3, "333", "333pass", 2013, 0));
es.insert(new employee(4, "222", "222pass", 2015, 0));
es.insert(new employee(5, "555", "555pass", 2014, 0)); /* dup */
typedef employee_set::nth_index<1>::type hire_index_t;
typedef employee_set::index<auth_t>::type auth_index_t;
cout << "Get a view to index #1 (m_hire).." << endl;
hire_index_t &hire_index = es.get<1>();
std::copy(hire_index.begin(), hire_index.end(), ostream_iterator<employee *>(cout, "\n"));
cout << "Get a view to index tag auth_t (m_auth).." << endl;
const auth_index_t &auth_index = es.get<auth_t>();
std::copy(auth_index.begin(), auth_index.end(), ostream_iterator<employee *>(cout, "\n"));
cout << "Find.." << endl;
hire_index_t::iterator it = hire_index.find(2015);
#if 0
employee *t = *it;
t->m_auth.m_name = "888";
/* must use replace() to notify changes in indexed fields */
hire_index.replace(it, t);
#else
hire_index.modify_key(it, boost::lambda::_1=1111);
int old_resign = (*it)->m_resign;
hire_index.modify(it, change_resign(2048), change_resign(old_resign));
#endif
cout << (*it) << endl;
cout << "Find all.." << endl;
pair<auth_index_t::const_iterator, auth_index_t::const_iterator> pr = auth_index.equal_range(auth("555", ""));
std::copy(pr.first, pr.second, ostream_iterator<employee *>(cout, "\n"));
/* clear */
for (employee_set::const_iterator it = es.begin(); it != es.end(); ++it) {
delete *it;
}
employee_set().swap(es);
return 0;
}